Here is a proposed patch, tell me what you think.

(note this also goes back to wait(1000) once every loop of the creation
thread, I did this to ensure that one call to awaken() will _always_ put
the thread in creation mode.

--Brandon

On Sat, 09/27/03 at 10:47:30 -0500, Brandon Low wrote:
> Ok, so I'm reading QThreadFactory ONE MORE TIME... There may be a
> problem, we might _want to_ overestimate available during create thread,
> return thread, but then underestimate it in destroy thread and get
> thread, because of the following:  what happens if by (relatively
> impossible, but it is _theoretically_ possible, and as freenet scales it
> will happen) some chance, the QThreadFactory's creator thread is able to
> keep calling createThread repeatedly but NONE of those threads that are
> created ever manage to get the countLock?  Then all of a sudden we have
> tons of extra threads around... createThread should inc. available as
> soon as it fires IMHO.
> 
> Thoughts?
> 
> Thanks,
> 
> Brandon
> _______________________________________________
> Devl mailing list
> [EMAIL PROTECTED]
> http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/devl
Index: src/freenet/thread/QThreadFactory.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/thread/QThreadFactory.java,v
retrieving revision 1.35
diff -u -r1.35 QThreadFactory.java
--- src/freenet/thread/QThreadFactory.java      27 Sep 2003 07:37:16 -0000      1.35
+++ src/freenet/thread/QThreadFactory.java      27 Sep 2003 16:00:50 -0000
@@ -29,7 +29,8 @@
 
     private final CountLock countLock = new CountLock();
     private int active = 0;
-    private int available = 0; // never more than number of threads on stack.
+    private int available = 0; //Must always include threads who's creations
+                               //or deletions are currently happening!
 
     private final NumLock numLock = new NumLock();
     private long threadNumber = 0;
@@ -80,19 +81,6 @@
                                                        Math.min(required, 
                                                                         
Math.max((int) (active * IDEAL_AVAILABLE_RATIO),
                                                                                       
   2 * MINIMUM_AVAILABLE_ABS));
-                                               if ( available > required &&
-                                                        available > active * 
MINIMUM_AVAILABLE_RATIO ) {
-                                                       try { 
-                                                               countLock.wait(500); 
-                                                       } catch ( InterruptedException 
ie ) {
-                                                               // active might have 
changed.
-                                                               // required must not 
increase.
-                                                               required = 
-                                                                       
Math.min(required, 
-                                                                                      
  Math.max((int) (active * IDEAL_AVAILABLE_RATIO),
-                                                                                      
                   2 * MINIMUM_AVAILABLE_ABS));
-                                                       }
-                                               }
                                                logAvailable = available;
                                                logActive = active;
                     } 
@@ -127,19 +115,6 @@
                                                        Math.max((int) (active * 
IDEAL_AVAILABLE_RATIO),
                                                                         
Math.max(allowed,
                                                                                       
   2 * MINIMUM_AVAILABLE_ABS));
-                                               if ( available < allowed &&
-                                                        available < active * 
MAXIMUM_AVAILABLE_RATIO ) {
-                                                       try { 
-                                                               countLock.wait(500); 
-                                                       } catch ( InterruptedException 
ie ) {
-                                                               // active might have 
changed.
-                                                               // allowed must not 
decrease.
-                                                               allowed = 
-                                                                       Math.max((int) 
(active * IDEAL_AVAILABLE_RATIO),
-                                                                                      
  Math.max(allowed,
-                                                                                      
                   2 * MINIMUM_AVAILABLE_ABS));
-                                                       }
-                                               }
                                                logAvailable = available;
                                                logActive = active;
                     } 
@@ -168,7 +143,7 @@
             }
                        synchronized(countLock) {
                                try { 
-                                       countLock.wait(500); 
+                                       countLock.wait(1000); 
                                } catch ( InterruptedException ie ) {}
                        }
         }
@@ -210,7 +185,10 @@
         QThread thread = null;
         synchronized(countLock) {
             active++;
-            available--; // never an overestimate
+            available--; //Aleays an underestimate
+                         //to ensure that once a get
+                         //starts it's thread is
+                         //replaced.
         }
         synchronized(headLock) {
             // hopefully this will not happen often.
@@ -228,7 +206,9 @@
                 newThreadNumber = ++threadNumber;
             }
                        synchronized(countLock) {
-                               available++; // correct the underestimate.
+                               available++; //correct the underestimate
+                             //_before_ actually creating
+                             //the thread!
                        }
                        thread = new QThread(newThreadNumber);
         }
@@ -249,14 +229,17 @@
                synchronized(numLock) {
                        newThreadNumber = ++threadNumber;
                }
+        synchronized(countLock) {
+            available++; //Always overestimate here
+                         //We don't want to spin
+                         //Starting more and more
+                         //creations w/o counting
+        }
                newThread = new QThread(newThreadNumber);
         synchronized(headLock) {
             newThread.next = headerThread;
             headerThread = newThread;
         }
-        synchronized(countLock) {
-            available++; // never an overestimate.
-        }
     }
 
     /**
@@ -266,14 +249,17 @@
      */
     private final void destroyThread() {
         QThread dyingThread;
-               synchronized(countLock) {
-                       if (available < 1) return;
-                       available--; // never an overestimate.
-               }
         synchronized(headLock) {
             dyingThread = headerThread;
                        headerThread = headerThread.next;
         }
+               synchronized(countLock) {
+                       if (available < 1) return;
+                       available--; //Always underestimate on
+                         //deletions, we don't want
+                         //to spin starting more
+                         //deletions
+               }
                dyingThread.die();
     }
 
@@ -281,13 +267,13 @@
      * Returns a thread to the stack when it is finished executing.
      */
     private final void returnThread(QThread returnThread) {
+        synchronized(countLock) {
+            active--;
+            available++; //Always an overestimate
+        }
         synchronized(headLock) {
             returnThread.next = headerThread;
             headerThread = returnThread;
-        }
-        synchronized(countLock) {
-            active--;
-            available++; // never an overestimate
         }
     }
 

Attachment: pgp00000.pgp
Description: PGP signature

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

Reply via email to