Update of /cvsroot/freenet/freenet/src/freenet
In directory sc8-pr-cvs1:/tmp/cvs-serv22073/src/freenet

Modified Files:
        OpenConnectionManager.java 
Log Message:
More locking improvements.
-Moved KillSurplusConnections to a thread of it's own, this is in the hopes of 
reducing contention for the highly contested lru lock in OpenConnectionManager
-Completely redid locking in QThreadFactory, locking the whole class for most of the 
operations in here didn't make sense, so I used several different locks to ensure 
synchronization w/o blocking threads trying to return themselves
(Committed at Zab's request)

Index: OpenConnectionManager.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/OpenConnectionManager.java,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -r1.107 -r1.108
--- OpenConnectionManager.java  23 Sep 2003 00:55:10 -0000      1.107
+++ OpenConnectionManager.java  26 Sep 2003 02:02:08 -0000      1.108
@@ -73,6 +73,10 @@
                logDEBUG = Core.logger.shouldLog(Logger.DEBUG, this);
         chs = new MultiValueTable(50, 3);
         openConns = 0;
+        SurplusKiller sk = new SurplusKiller(lru,maxConnections);
+        Thread skt = new Thread(sk,"Surplus connection killing thread");
+        skt.setDaemon(true);
+        skt.start();
     }
 
     /**
@@ -104,8 +108,9 @@
                synchronized(openConnsSync) {
                        openConns++;
                }
-               
-        KillSurplusConnections();
+               synchronized(lru) {
+            lru.notifyAll();
+        }
     }
     
     // Removing a connection that isn't in the OCM is a 
@@ -466,63 +471,82 @@
                        }
                }
     }
-       
+    
        /**
         * Kills off one or more connections to ensure that we stay below the 
connection limit
         * This method is appropriate to call after a connection has been added to the 
OCM 
         */
-       private void KillSurplusConnections() {
-        // Dump LRU idle connection.
-        //
-        // Note: You don't want to dump the simple LRU connection
-        //       because under heavy load the LRU connections are
-        //       the ones that are transferring data.
-        //       
-        ConnectionHandler oldest = null;
-               while (true) {
-                       synchronized (lru) {
-                               
-                               if (maxConnections > 0 && lru.size() > maxConnections) 
{
-                                       
-                                       // Dump an idle connection if possible.
-                                       for (Enumeration e = lru.elements(); 
e.hasMoreElements();) {
-                                               ConnectionHandler candidate = 
-                                                       
(ConnectionHandler)e.nextElement();
-                                               if (!(candidate.sending() || 
candidate.receiving())) {
-                                                       if(oldest != null) {
-                                                               // If the oldest is 
open and the candidate is closed...
-                                                               if(oldest.isOpen() && 
(!candidate.isOpen()))
-                                                                       oldest = null;
-                                                               // Or the oldest is an 
only-conn-to-this-RTNode and the 
-                                                               // candidate is not... 
then use the candidate
-                                                               else 
if((!onlyRTNodeConn(candidate)) && onlyRTNodeConn(oldest))
-                                                                       oldest = null;
-                                                       }
-                                                       if(oldest == null) {
-                                                               oldest = candidate;
-                                                               if(!oldest.isOpen()) 
break;
-                                                       }
-                                                       // Otherwise wait for the best 
open conn
-                                                       //lru.remove(candidate);
-                                               }
-                                       }
-                                       if (oldest == null) {
-                                               // Not good. This connection will most 
likely
-                                               // be restarted, causing even more 
traffic :-(
-                        //System.err.println("!KILLED OPEN CONNECTION!");
-                                               oldest = (ConnectionHandler)lru.pop();
-                                       }
-                                       
-                               } else break; // break outer loop - we have killed 
enough connections
-                       }
-                       if (oldest != null) {
-                               
Core.diagnostics.occurrenceBinomial("connectionTimedout", 1, 0);
-                               oldest.terminate();
-                               oldest = null;
-                       }
-               }
-       }
-       
+    private class SurplusKiller implements Runnable {
+
+        private LRUQueue lru;
+        private int maxConnections;
+        
+        public SurplusKiller(LRUQueue lru,int maxConnections) {
+            this.lru = lru;
+            this.maxConnections = maxConnections;
+        }
+        
+        public void run() {
+            while (true) {
+                // Dump LRU idle connection.
+                //
+                // Note: You don't want to dump the simple LRU connection
+                //       because under heavy load the LRU connections are
+                //       the ones that are transferring data.
+                //       
+                ConnectionHandler oldest = null;
+                while (true) {
+                    synchronized (lru) {
+                        if ( !(maxConnections > 0 && lru.size() > maxConnections) ) {
+                            try {
+                                // wait till we are awakened - no more need to die
+                                lru.wait();
+                            } catch ( InterruptedException ie ) {
+                            }
+                        } else {
+                            // Dump an idle connection if possible.
+                            for (Enumeration e = lru.elements(); 
e.hasMoreElements();) {
+                                ConnectionHandler candidate = 
+                                    (ConnectionHandler)e.nextElement();
+                                if (!(candidate.sending() || candidate.receiving())) {
+                                    // If the oldest is open and the candidate is 
closed...
+                                    if( !candidate.isOpen() ) {
+                                        oldest = candidate;
+                                        break;
+                                    } else if ( oldest != null ) {
+                                        //This can only happen if it closes during 
the run of
+                                        //this loop, very unlikely but _anything_ 
which could
+                                        //keep us from running onlyRTNodeConn is a 
good thing
+                                        //because that involves locking hashtables, 
BigInteger
+                                        //math and badness like that.
+                                        if ( oldest != null && (!oldest.isOpen()) )
+                                            break;
+                                        // If the oldest is an 
only-conn-to-this-RTNode and the 
+                                        // candidate is not... then use the candidate
+                                        if(onlyRTNodeConn(oldest) && 
(!onlyRTNodeConn(candidate)) )
+                                            oldest = candidate;
+                                    } else {
+                                        oldest = candidate;
+                                    }
+                                }
+                            }
+                            if (oldest == null) {
+                                // Not good. This connection will most likely
+                                // be restarted, causing even more traffic :-(
+                                oldest = (ConnectionHandler)lru.pop();
+                            }
+
+                        }
+                    }
+                    if (oldest != null) {
+                        Core.diagnostics.occurrenceBinomial("connectionTimedout", 1, 
0);
+                        oldest.terminate();
+                        oldest = null;
+                    }
+                }
+            }
+        }
+    }
     /**
      * Returns a free connection, making a new one if none is available.
      */

_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to