From 6153d05573fad5a89644d3c76bddb8edcb426207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ce=CC=81sar=20Luis=20Alvargonza=CC=81lez?= Date: Thu, 9 Sep 2021 19:13:37 +0100 Subject: [PATCH] Fix "TryLock interrupted keeps renewing lock indefinitely" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: César Luis Alvargonzález --- .../java/org/redisson/RedissonBaseLock.java | 8 ++++++- .../redisson/command/CommandAsyncService.java | 1 + .../java/org/redisson/RedissonLockTest.java | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/redisson/src/main/java/org/redisson/RedissonBaseLock.java b/redisson/src/main/java/org/redisson/RedissonBaseLock.java index b366f31e4..6203d3d4e 100644 --- a/redisson/src/main/java/org/redisson/RedissonBaseLock.java +++ b/redisson/src/main/java/org/redisson/RedissonBaseLock.java @@ -174,7 +174,13 @@ public abstract class RedissonBaseLock extends RedissonExpirable implements RLoc oldEntry.addThreadId(threadId); } else { entry.addThreadId(threadId); - renewExpiration(); + try { + renewExpiration(); + } finally { + if (Thread.currentThread().isInterrupted()) { + cancelExpirationRenewal(threadId); + } + } } } diff --git a/redisson/src/main/java/org/redisson/command/CommandAsyncService.java b/redisson/src/main/java/org/redisson/command/CommandAsyncService.java index e34f2c51a..95ddd5d12 100644 --- a/redisson/src/main/java/org/redisson/command/CommandAsyncService.java +++ b/redisson/src/main/java/org/redisson/command/CommandAsyncService.java @@ -112,6 +112,7 @@ public class CommandAsyncService implements CommandAsyncExecutor { try { future.await(); } catch (InterruptedException e) { + future.cancel(true); Thread.currentThread().interrupt(); throw new RedisException(e); } diff --git a/redisson/src/test/java/org/redisson/RedissonLockTest.java b/redisson/src/test/java/org/redisson/RedissonLockTest.java index b412d9d5c..414f46fa8 100644 --- a/redisson/src/test/java/org/redisson/RedissonLockTest.java +++ b/redisson/src/test/java/org/redisson/RedissonLockTest.java @@ -111,6 +111,29 @@ public class RedissonLockTest extends BaseConcurrentTest { runner.stop(); } + @Test + public void testLockIsNotRenewedAfterInterruptedTryLock() throws InterruptedException { + final CountDownLatch countDownLatch = new CountDownLatch(1); + RLock lock = redisson.getLock("myLock"); + assertThat(lock.isLocked()).isFalse(); + + Thread thread = new Thread(() -> { + countDownLatch.countDown(); + if (!lock.tryLock()) { + return; + } + lock.unlock(); + }); + thread.start(); + countDownLatch.await(); + // let the tcp request be sent out + TimeUnit.MILLISECONDS.sleep(5); + thread.interrupt(); + TimeUnit.SECONDS.sleep(45); + + assertThat(lock.isLocked()).isFalse(); + } + @Test public void testRedisFailed() { Assertions.assertThrows(WriteRedisConnectionException.class, () -> {