From ebe16f85cb004d76b54aac4883143e66e5c22f9b Mon Sep 17 00:00:00 2001 From: Pankaj Date: Wed, 17 Jul 2019 21:26:05 +0530 Subject: [PATCH] HBASE-22706 Backport HBASE-21292 to branch-1 --- .../java/org/apache/hadoop/hbase/util/IdLock.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/IdLock.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/IdLock.java index fedf951c26..abd53d715e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/IdLock.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/IdLock.java @@ -81,6 +81,17 @@ public class IdLock { existing.wait(); } catch (InterruptedException e) { --existing.numWaiters; // Remove ourselves from waiters. + // HBASE-21292/HBASE-22706 + // There is a rare case that interrupting and the lock owner thread call + // releaseLockEntry at the same time. Since the owner thread found there + // still one waiting, it won't remove the entry from the map. If the interrupted + // thread is the last one waiting on the lock, and since an exception is thrown, + // the 'existing' entry will stay in the map forever. Later threads which try to + // get this lock will stuck in a infinite loop because + // existing = map.putIfAbsent(entry.id, entry)) != null and existing.isLocked=false. + if (!existing.isLocked && existing.numWaiters == 0) { + map.remove(existing.id); + } throw new InterruptedIOException( "Interrupted waiting to acquire sparse lock"); } -- 2.17.1