Repository: cassandra
Updated Branches:
  refs/heads/cassandra-3.11 6d0e95af7 -> eb717f154
  refs/heads/trunk 855dd0eee -> 6eb2758e4


Deadlock in AbstractCommitLogSegmentManager

Patch by Fedor Bobin; Reviewed by Ariel Weisberg for CASSANDRA-13652


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/eb717f15
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/eb717f15
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/eb717f15

Branch: refs/heads/cassandra-3.11
Commit: eb717f154bd24453273d7175006fdef75e5724c2
Parents: 6d0e95a
Author: Fedor Bobin <fuudtorrent...@gmail.com>
Authored: Tue Jul 11 15:10:28 2017 -0400
Committer: Ariel Weisberg <aweisb...@apple.com>
Committed: Mon Jul 17 13:50:09 2017 -0700

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../AbstractCommitLogSegmentManager.java        | 11 +++++------
 .../cassandra/utils/concurrent/WaitQueue.java   | 20 ++++++++++++++++++++
 3 files changed, 26 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/eb717f15/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 8abf1f4..e7a10f5 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.11.1
+ * Deadlock in AbstractCommitLogSegmentManager (CASSANDRA-13652)
  * Duplicate the buffer before passing it to analyser in SASI operation 
(CASSANDRA-13512)
  * Properly evict pstmts from prepared statements cache (CASSANDRA-13641)
 Merged from 3.0:

http://git-wip-us.apache.org/repos/asf/cassandra/blob/eb717f15/src/java/org/apache/cassandra/db/commitlog/AbstractCommitLogSegmentManager.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/commitlog/AbstractCommitLogSegmentManager.java
 
b/src/java/org/apache/cassandra/db/commitlog/AbstractCommitLogSegmentManager.java
old mode 100644
new mode 100755
index 0ab941b..7f3c9f8
--- 
a/src/java/org/apache/cassandra/db/commitlog/AbstractCommitLogSegmentManager.java
+++ 
b/src/java/org/apache/cassandra/db/commitlog/AbstractCommitLogSegmentManager.java
@@ -22,7 +22,7 @@ import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.LockSupport;
+import java.util.function.BooleanSupplier;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.util.concurrent.*;
@@ -82,6 +82,8 @@ public abstract class AbstractCommitLogSegmentManager
     private Thread managerThread;
     protected final CommitLog commitLog;
     private volatile boolean shutdown;
+    private final BooleanSupplier managerThreadWaitCondition = () -> 
(availableSegment == null && !atSegmentBufferLimit()) || shutdown;
+    private final WaitQueue managerThreadWaitQueue = new WaitQueue();
 
     private static final SimpleCachedBufferPool bufferPool =
         new 
SimpleCachedBufferPool(DatabaseDescriptor.getCommitLogMaxCompressionBuffersInPool(),
 DatabaseDescriptor.getCommitLogSegmentSize());
@@ -124,8 +126,6 @@ public abstract class AbstractCommitLogSegmentManager
                         // Writing threads are not waiting for new segments, 
we can spend time on other tasks.
                         // flush old Cfs if we're full
                         maybeFlushToReclaim();
-
-                        LockSupport.park();
                     }
                     catch (Throwable t)
                     {
@@ -140,8 +140,7 @@ public abstract class AbstractCommitLogSegmentManager
                         // shutting down-- nothing more can or needs to be 
done in that case.
                     }
 
-                    while (availableSegment != null || atSegmentBufferLimit() 
&& !shutdown)
-                        LockSupport.park();
+                    WaitQueue.waitOnCondition(managerThreadWaitCondition, 
managerThreadWaitQueue);
                 }
             }
         };
@@ -530,7 +529,7 @@ public abstract class AbstractCommitLogSegmentManager
 
     void wakeManager()
     {
-        LockSupport.unpark(managerThread);
+        managerThreadWaitQueue.signalAll();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/eb717f15/src/java/org/apache/cassandra/utils/concurrent/WaitQueue.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/concurrent/WaitQueue.java 
b/src/java/org/apache/cassandra/utils/concurrent/WaitQueue.java
index be271b6..5b453b0 100644
--- a/src/java/org/apache/cassandra/utils/concurrent/WaitQueue.java
+++ b/src/java/org/apache/cassandra/utils/concurrent/WaitQueue.java
@@ -22,6 +22,7 @@ import java.util.Iterator;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import java.util.concurrent.locks.LockSupport;
+import java.util.function.BooleanSupplier;
 
 import com.codahale.metrics.Timer;
 
@@ -518,4 +519,23 @@ public final class WaitQueue
     {
         return new AllSignal(signals);
     }
+
+    /**
+     * Loops waiting on the supplied condition and WaitQueue and will not 
return until the condition is true
+     */
+    public static void waitOnCondition(BooleanSupplier condition, WaitQueue 
queue)
+    {
+        while (!condition.getAsBoolean())
+        {
+            Signal s = queue.register();
+            if (!condition.getAsBoolean())
+            {
+                s.awaitUninterruptibly();
+            }
+            else
+            {
+                s.cancel();
+            }
+        }
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to