tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fha...@apache.org
Subject svn commit: r707670 - /tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java
Date Fri, 24 Oct 2008 16:14:07 GMT
Author: fhanik
Date: Fri Oct 24 09:14:07 2008
New Revision: 707670

URL: http://svn.apache.org/viewvc?rev=707670&view=rev
Log:
During a read or write timeout, we were cancelling the main key, this is fine for regular
IO, but for Comet IO, this will cause events to stop since we remove the socket from the main
selector

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java?rev=707670&r1=707669&r2=707670&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java Fri Oct 24 09:14:07
2008
@@ -81,6 +81,7 @@
     public int write(ByteBuffer buf, NioChannel socket, long writeTimeout,MutableInteger
lastWrite) throws IOException {
         SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
         if ( key == null ) throw new IOException("Key no longer registered");
+        KeyReference reference = new KeyReference();
         KeyAttachment att = (KeyAttachment) key.attachment();
         int written = 0;
         boolean timedout = false;
@@ -101,7 +102,7 @@
                 }
                 try {
                     if ( att.getWriteLatch()==null || att.getWriteLatch().getCount()==0)
att.startWriteLatch(1);
-                    poller.add(att,SelectionKey.OP_WRITE);
+                    poller.add(att,SelectionKey.OP_WRITE,reference);
                     att.awaitWriteLatch(writeTimeout,TimeUnit.MILLISECONDS);
                 }catch (InterruptedException ignore) {
                     Thread.interrupted();
@@ -122,9 +123,10 @@
                 throw new SocketTimeoutException();
         } finally {
             poller.remove(att,SelectionKey.OP_WRITE);
-            if (timedout && key != null) {
-                poller.cancelKey(socket, key);
+            if (timedout && reference.key!=null) {
+                poller.cancelKey(reference.key);
             }
+            reference.key = null;
         }
         return written;
     }
@@ -145,6 +147,7 @@
     public int read(ByteBuffer buf, NioChannel socket, long readTimeout) throws IOException
{
         SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
         if ( key == null ) throw new IOException("Key no longer registered");
+        KeyReference reference = new KeyReference();
         KeyAttachment att = (KeyAttachment) key.attachment();
         int read = 0;
         boolean timedout = false;
@@ -162,7 +165,7 @@
                 }
                 try {
                     if ( att.getReadLatch()==null || att.getReadLatch().getCount()==0) att.startReadLatch(1);
-                    poller.add(att,SelectionKey.OP_READ);
+                    poller.add(att,SelectionKey.OP_READ, reference);
                     att.awaitReadLatch(readTimeout,TimeUnit.MILLISECONDS);
                 }catch (InterruptedException ignore) {
                     Thread.interrupted();
@@ -182,9 +185,10 @@
                 throw new SocketTimeoutException();
         } finally {
             poller.remove(att,SelectionKey.OP_READ);
-            if (timedout && key != null) {
-                poller.cancelKey(socket,key);
+            if (timedout && reference.key!=null) {
+                poller.cancelKey(reference.key);
             }
+            reference.key = null;
         }
         return read;
     }
@@ -196,7 +200,7 @@
         protected ConcurrentLinkedQueue<Runnable> events = new ConcurrentLinkedQueue<Runnable>();
         public void disable() { run = false; selector.wakeup();}
         protected AtomicInteger wakeupCounter = new AtomicInteger(0);
-        public void cancelKey(final NioChannel socket, final SelectionKey key) {
+        public void cancelKey(final SelectionKey key) {
             Runnable r = new Runnable() {
                 public void run() {
                     key.cancel();
@@ -219,7 +223,7 @@
             }
         }
         
-        public void add(final KeyAttachment key, final int ops) {
+        public void add(final KeyAttachment key, final int ops, final KeyReference ref) {
             Runnable r = new Runnable() {
                 public void run() {
                     if ( key == null ) return;
@@ -231,6 +235,7 @@
                     try {
                         if (sk == null) {
                             sk = ch.register(selector, ops, key);
+                            ref.key = sk;
                         } else if (!sk.isValid()) {
                             cancel(sk,key,ops);
                         } else {
@@ -360,15 +365,30 @@
             }catch( Exception ignore ) {
                 if (log.isDebugEnabled())log.debug("",ignore);
             }
+            try {
+                selector.close();//Close the connector
+            }catch( Exception ignore ) {
+                if (log.isDebugEnabled())log.debug("",ignore);
+            }
         }
         
         public void countDown(CountDownLatch latch) {
             if ( latch == null ) return;
             latch.countDown();
         }
+    }
+    
+    public class KeyReference {
+        SelectionKey key = null;
         
-        
-        
+        @Override
+        public void finalize() {
+            if (key!=null && key.isValid()) {
+                log.warn("Possible key leak, cancelling key in the finalizer.");
+                try {key.cancel();}catch (Exception ignore){}
+            }
+            key = null;
+        }
     }
 
 }
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message