Return-Path: X-Original-To: apmail-tomcat-dev-archive@www.apache.org Delivered-To: apmail-tomcat-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DC6BB95CB for ; Mon, 5 Nov 2012 00:25:26 +0000 (UTC) Received: (qmail 60434 invoked by uid 500); 5 Nov 2012 00:25:25 -0000 Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org Received: (qmail 60367 invoked by uid 500); 5 Nov 2012 00:25:25 -0000 Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Developers List" Delivered-To: mailing list dev@tomcat.apache.org Received: (qmail 60355 invoked by uid 99); 5 Nov 2012 00:25:25 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Nov 2012 00:25:25 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Nov 2012 00:25:24 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 714DA23888E7 for ; Mon, 5 Nov 2012 00:25:04 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1405682 - in /tomcat/tc7.0.x/trunk: ./ java/org/apache/catalina/tribes/transport/ReceiverBase.java java/org/apache/catalina/tribes/transport/nio/NioReceiver.java webapps/docs/changelog.xml Date: Mon, 05 Nov 2012 00:25:04 -0000 To: dev@tomcat.apache.org From: markt@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121105002504.714DA23888E7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: markt Date: Mon Nov 5 00:25:03 2012 New Revision: 1405682 URL: http://svn.apache.org/viewvc?rev=1405682&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54086 Ensure only a single thread tries to close the selector. Prior to this change both the NioReceiverThread and the thread that stops it called closeSelector() I also reviewed all other accesses to this.selector and fixed a handful of other potential threading issues. Modified: tomcat/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1405681 Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java?rev=1405682&r1=1405681&r2=1405682&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java Mon Nov 5 00:25:03 2012 @@ -63,7 +63,7 @@ public abstract class ReceiverBase imple private int udpRxBufSize = 43800; private int udpTxBufSize = 25188; - private boolean listen = false; + private volatile boolean listen = false; private RxTaskPool pool; private boolean direct = true; private long tcpSelectorTimeout = 5000; Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java?rev=1405682&r1=1405681&r2=1405682&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java Mon Nov 5 00:25:03 2012 @@ -30,6 +30,7 @@ import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.LinkedList; import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; import org.apache.catalina.tribes.io.ObjectReader; import org.apache.catalina.tribes.transport.AbstractRxTask; @@ -58,7 +59,7 @@ public class NioReceiver extends Receive */ private static final String info = "NioReceiver/1.0"; - private Selector selector = null; + private AtomicReference selector = new AtomicReference(); private ServerSocketChannel serverChannel = null; private DatagramChannel datagramChannel = null; @@ -136,7 +137,7 @@ public class NioReceiver extends Receive // Selector.open() isn't thread safe // http://bugs.sun.com/view_bug.do?bug_id=6427854 // Affects 1.6.0_29, fixed in 1.7.0_01 - selector = Selector.open(); + this.selector.set(Selector.open()); } // set the port the server channel will listen to //serverSocket.bind(new InetSocketAddress(getBind(), getTcpListenPort())); @@ -144,7 +145,7 @@ public class NioReceiver extends Receive // set non-blocking mode for the listening socket serverChannel.configureBlocking(false); // register the ServerSocketChannel with the Selector - serverChannel.register(selector, SelectionKey.OP_ACCEPT); + serverChannel.register(this.selector.get(), SelectionKey.OP_ACCEPT); //set up the datagram channel if (this.getUdpPort()>0) { @@ -165,12 +166,13 @@ public class NioReceiver extends Receive } public void addEvent(Runnable event) { + Selector selector = this.selector.get(); if ( selector != null ) { synchronized (events) { events.add(event); } if ( log.isTraceEnabled() ) log.trace("Adding event to selector:"+event); - if ( isListening() && selector!=null ) selector.wakeup(); + if ( isListening() ) selector.wakeup(); } } @@ -210,7 +212,7 @@ public class NioReceiver extends Receive long now = System.currentTimeMillis(); if ( (now-lastCheck) < getSelectorTimeout() ) return; //timeout - Selector tmpsel = selector; + Selector tmpsel = this.selector.get(); Set keys = (isListening()&&tmpsel!=null)?tmpsel.keys():null; if ( keys == null ) return; for (Iterator iter = keys.iterator(); iter.hasNext();) { @@ -263,7 +265,7 @@ public class NioReceiver extends Receive setListen(true); // Avoid NPEs if selector is set to null on stop. - Selector selector = this.selector; + Selector selector = this.selector.get(); if (selector!=null && datagramChannel!=null) { ObjectReader oreader = new ObjectReader(MAX_UDP_SIZE); //max size for a datagram packet @@ -359,6 +361,7 @@ public class NioReceiver extends Receive */ protected void stopListening() { setListen(false); + Selector selector = this.selector.get(); if (selector != null) { try { selector.wakeup(); @@ -366,14 +369,13 @@ public class NioReceiver extends Receive } catch (Exception x) { log.error("Unable to close cluster receiver selector.", x); } finally { - selector = null; + this.selector.set(null); } } } private void closeSelector() throws IOException { - Selector selector = this.selector; - this.selector = null; + Selector selector = this.selector.getAndSet(null); if (selector==null) return; try { Iterator it = selector.keys().iterator(); Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1405682&r1=1405681&r2=1405682&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Mon Nov 5 00:25:03 2012 @@ -171,6 +171,10 @@ Add getSessionIdsFull operation to mbeans-descriptor. listSessionIdsFull no longer exist. (kfujino) + + 54086: Fix threading issue when stopping an + NioReceiver. (markt) + --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org For additional commands, e-mail: dev-help@tomcat.apache.org