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