Browse Source

Fixed an NPE (apparently harmless) for a certain connection
teardown ordering and added some logging just to be sure
the channels are getting closed.


git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7153 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

PSp..om 14 năm trước cách đây
mục cha
commit
d3364b4622

+ 17 - 10
engine/src/networking/com/jme3/network/kernel/tcp/SelectorKernel.java

@@ -112,7 +112,7 @@ public class SelectorKernel extends AbstractKernel
         }
     }
 
-    public void broadcast( Filter<? super Endpoint> filter, ByteBuffer data, boolean reliable, 
+    public void broadcast( Filter<? super Endpoint> filter, ByteBuffer data, boolean reliable,
                            boolean copy )
     {
         if( !reliable )
@@ -133,7 +133,7 @@ public class SelectorKernel extends AbstractKernel
                 continue;
 
             // Give it the data... but let each endpoint track their
-            // own completion over the shared array of bytes by 
+            // own completion over the shared array of bytes by
             // duplicating it
             p.send( data.duplicate(), false, false );
         }
@@ -164,7 +164,7 @@ public class SelectorKernel extends AbstractKernel
 
         // Enqueue an endpoint event for the listeners
         addEvent( EndpointEvent.createRemove( this, p ) );
-        
+
         // If there are no pending messages then add one so that the
         // kernel-user knows to wake up if it is only listening for
         // envelopes.
@@ -174,7 +174,7 @@ public class SelectorKernel extends AbstractKernel
             // to check again.
             addEnvelope( EVENTS_PENDING );
         }
-    }    
+    }
 
     /**
      *  Called by the endpoints when they need to be closed.
@@ -285,10 +285,10 @@ public class SelectorKernel extends AbstractKernel
             // efficiently done as change requests... or simply
             // keeping a thread-safe set of endpoints with pending
             // writes.  For most cases, it shouldn't matter.
-            for( Map.Entry<NioEndpoint,SelectionKey> e : endpointKeys.entrySet() ) {            
+            for( Map.Entry<NioEndpoint,SelectionKey> e : endpointKeys.entrySet() ) {
                 if( e.getKey().hasPending() ) {
                     e.getValue().interestOps(SelectionKey.OP_WRITE);
-                }                    
+                }
             }
         }
 
@@ -318,7 +318,13 @@ public class SelectorKernel extends AbstractKernel
 
         protected void cancel( NioEndpoint p ) throws IOException
         {
+            log.log( Level.INFO, "Closing endpoint:{0}.", p );
             SelectionKey key = endpointKeys.remove(p);
+            if( key == null ) {
+                log.log( Level.INFO, "Endpoint already closed:{0}.", p );
+                return;  // already closed it
+            }                
+
             SocketChannel c = (SocketChannel)key.channel();
 
             // Note: key.cancel() is specifically thread safe.  One of
@@ -332,6 +338,7 @@ public class SelectorKernel extends AbstractKernel
         protected void cancel( SelectionKey key, SocketChannel c ) throws IOException
         {
             NioEndpoint p = (NioEndpoint)key.attachment();
+            log.log( Level.INFO, "Closing channel endpoint:{0}.", p );
             endpointKeys.remove(p);
 
             key.cancel();
@@ -375,13 +382,13 @@ public class SelectorKernel extends AbstractKernel
             if( current == NioEndpoint.CLOSE_MARKER ) {
                 // This connection wants to be closed now
                 closeEndpoint(p);
-                
+
                 // Nothing more to do
-                return;   
+                return;
             }
-            
+
             c.write( current );
-            
+
             // If we wrote all of that packet then we need to remove it
             if( current.remaining() == 0 ) {
                 p.removePending();