From e76d28a768bd530591beaae863ee993e817ce2be Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 12 Sep 2016 15:32:01 +0300 Subject: [PATCH] Check that RLock still belongs to owner during renewal expiration. #597 --- .../main/java/org/redisson/RedissonLock.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonLock.java b/redisson/src/main/java/org/redisson/RedissonLock.java index d1a7e7baa..3a9e09a2e 100644 --- a/redisson/src/main/java/org/redisson/RedissonLock.java +++ b/redisson/src/main/java/org/redisson/RedissonLock.java @@ -148,7 +148,7 @@ public class RedissonLock extends RedissonExpirable implements RLock { return get(tryAcquireAsync(leaseTime, unit, Thread.currentThread().getId())); } - private RFuture tryAcquireOnceAsync(long leaseTime, TimeUnit unit, long threadId) { + private RFuture tryAcquireOnceAsync(long leaseTime, TimeUnit unit, final long threadId) { if (leaseTime != -1) { return tryLockInnerAsync(leaseTime, unit, threadId, RedisCommands.EVAL_NULL_BOOLEAN); } @@ -163,14 +163,14 @@ public class RedissonLock extends RedissonExpirable implements RLock { Boolean ttlRemaining = future.getNow(); // lock acquired if (ttlRemaining) { - scheduleExpirationRenewal(); + scheduleExpirationRenewal(threadId); } } }); return ttlRemainingFuture; } - private RFuture tryAcquireAsync(long leaseTime, TimeUnit unit, long threadId) { + private RFuture tryAcquireAsync(long leaseTime, TimeUnit unit, final long threadId) { if (leaseTime != -1) { return tryLockInnerAsync(leaseTime, unit, threadId, RedisCommands.EVAL_LONG); } @@ -185,7 +185,7 @@ public class RedissonLock extends RedissonExpirable implements RLock { Long ttlRemaining = future.getNow(); // lock acquired if (ttlRemaining == null) { - scheduleExpirationRenewal(); + scheduleExpirationRenewal(threadId); } } }); @@ -197,7 +197,7 @@ public class RedissonLock extends RedissonExpirable implements RLock { return get(tryLockAsync()); } - private void scheduleExpirationRenewal() { + private void scheduleExpirationRenewal(final long threadId) { if (expirationRenewalMap.containsKey(getEntryName())) { return; } @@ -205,7 +205,15 @@ public class RedissonLock extends RedissonExpirable implements RLock { Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() { @Override public void run(Timeout timeout) throws Exception { - RFuture future = expireAsync(internalLockLeaseTime, TimeUnit.MILLISECONDS); + + RFuture future = commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, + "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " + + "redis.call('pexpire', KEYS[1], ARGV[1]); " + + "return 1; " + + "end; " + + "return 0;", + Collections.singletonList(getName()), internalLockLeaseTime, getLockName(threadId)); + future.addListener(new FutureListener() { @Override public void operationComplete(Future future) throws Exception { @@ -217,7 +225,7 @@ public class RedissonLock extends RedissonExpirable implements RLock { if (future.getNow()) { // reschedule itself - scheduleExpirationRenewal(); + scheduleExpirationRenewal(threadId); } } });