From 28c39a31832145cd7568099d65201a6f01f651c5 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 20 Dec 2016 15:15:57 +0100 Subject: [PATCH] Ensure we use a MPMC queue in ThreadDeathWatcher as it may be used from multiple threads at the same time. Motivation: We used a MPSC queue in ThreadDeathWatcher and checked if it empty via isEmpty() from multiple threads if very unlucky. Depending on the implementation this is not safe and may even produce things like live-locks. Modifications: Change to use a MPMC queue. Result: No more risk to run into issues when multiple threads call watch(...) / unwatch(...) concurrently. --- common/src/main/java/io/netty/util/ThreadDeathWatcher.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/io/netty/util/ThreadDeathWatcher.java b/common/src/main/java/io/netty/util/ThreadDeathWatcher.java index d43b6bf4af..5fb21665d2 100644 --- a/common/src/main/java/io/netty/util/ThreadDeathWatcher.java +++ b/common/src/main/java/io/netty/util/ThreadDeathWatcher.java @@ -17,7 +17,6 @@ package io.netty.util; import io.netty.util.concurrent.DefaultThreadFactory; -import io.netty.util.internal.PlatformDependent; import io.netty.util.internal.StringUtil; import io.netty.util.internal.SystemPropertyUtil; import io.netty.util.internal.logging.InternalLogger; @@ -26,6 +25,7 @@ import io.netty.util.internal.logging.InternalLoggerFactory; import java.util.ArrayList; import java.util.List; import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -44,7 +44,9 @@ public final class ThreadDeathWatcher { // visible for testing static final ThreadFactory threadFactory; - private static final Queue pendingEntries = PlatformDependent.newMpscQueue(); + // Use a MPMC queue as we may end up checking isEmpty() from multiple threads which may not be allowed to do + // concurrently depending on the implemenation of it in a MPSC queue. + private static final Queue pendingEntries = new ConcurrentLinkedQueue(); private static final Watcher watcher = new Watcher(); private static final AtomicBoolean started = new AtomicBoolean(); private static volatile Thread watcherThread;