Fixed - RReadWriteLock.readLock().isLocked() method returns incorrect result if acquired by writeLock owner thread. #4400

pull/5361/head
Nikita Koksharov 1 year ago
parent c49dbfdc0e
commit 365d6b916e

@ -195,9 +195,15 @@ public class RedissonReadLock extends RedissonLock implements RLock {
@Override
public boolean isLocked() {
RFuture<String> future = commandExecutor.writeAsync(getRawName(), StringCodec.INSTANCE, RedisCommands.HGET, getRawName(), "mode");
String res = get(future);
return "read".equals(res);
RFuture<Boolean> future = commandExecutor.evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
"local mode = redis.call('hget', KEYS[1], 'mode'); " +
"if (mode == 'read') or (mode == 'write' and redis.call('hlen', KEYS[1]) > 2) then " +
"return 1; " +
"end; " +
"return 0; ",
Arrays.asList(getRawName()));
return get(future);
}
}

@ -1,36 +1,27 @@
package org.redisson;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.awaitility.Awaitility.await;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.redisson.ClusterRunner.ClusterProcesses;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.security.SecureRandom;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.redisson.ClusterRunner.ClusterProcesses;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.awaitility.Awaitility.await;
public class RedissonReadWriteLockTest extends BaseConcurrentTest {
@ -76,6 +67,18 @@ public class RedissonReadWriteLockTest extends BaseConcurrentTest {
Awaitility.await().between(8, TimeUnit.SECONDS, 10, TimeUnit.SECONDS).untilTrue(flag);
}
@Test
public void testReadLockIsLocked() throws InterruptedException {
RReadWriteLock readWriteLock = redisson.getReadWriteLock("TEST");
RLock writeLock = readWriteLock.writeLock();
RLock readLock = readWriteLock.readLock();
writeLock.lock();
assertThat(readLock.isLocked()).isFalse();
assertThat(readLock.tryLock(10, TimeUnit.SECONDS)).isTrue();
assertThat(readLock.isLocked()).isTrue();
}
@Test
public void testReadLockExpirationRenewal() throws InterruptedException {
int threadCount = 50;

Loading…
Cancel
Save