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

Modified Files:
        QThreadFactory.java 
Log Message:
Minor changes, theoretical bug fix.
If there were very few active threads,
it used to delete threads below 2*absoluteminimum.
getThread was missing a synchronize(thread), which
was the reason we needed that timed wait which
was deleted last revision.


Index: QThreadFactory.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/thread/QThreadFactory.java,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- QThreadFactory.java 10 Oct 2003 19:15:36 -0000      1.40
+++ QThreadFactory.java 14 Oct 2003 16:38:34 -0000      1.41
@@ -86,8 +86,9 @@
                                doLog = false;
                 int allowed;
                                countLock.snap(snap);
-                               // start with a maximal allowed value.
-                               allowed = Math.max((int)(snap.active * 
MAXIMUM_AVAILABLE_RATIO),2 * MINIMUM_AVAILABLE_ABS);
+                               // Start with a maximal allowed value.
+                               allowed = Math.max((int)(snap.active * 
MAXIMUM_AVAILABLE_RATIO),
+                                                                  2 * 
MINIMUM_AVAILABLE_ABS);
                                // Repeatedly remove a thread from the stack and 
signal it to die.
                                // But if all of the threads have meanwhile started 
jobs, then
                                // do nothing, and the loop will terminate with 
snap.available == 0
@@ -98,11 +99,14 @@
                                                // but it can never make 
headLock.pop() be null.
                                                headLock.pop().die();
                                        }
-                    // Let there be up to maximum threads sitting
-                    // around, I think this will reduce thread flux
-                    // a lot which should help CPU usage further
+                    // Let there be up to relative maximum threads
+                    // sitting around.  This will reduce thread flux a
+                    // lot which should help CPU usage further.  But
+                    // don't let it go below 2 * absolute minimum.
                                        allowed = 
-                                               Math.max((int) (snap.active * 
MAXIMUM_AVAILABLE_RATIO), allowed);
+                                               Math.max((int) (snap.active * 
MAXIMUM_AVAILABLE_RATIO),
+                                                                Math.max(allowed, // 
allowed must not decrease.
+                                                                                 2 * 
MINIMUM_AVAILABLE_ABS));
                                } 
                                if (logDEBUG && doLog)
                                        Core.logger.log(this,"Thread creation thread 
past destruction loop" + 
@@ -169,9 +173,13 @@
         } else {
                        thread = headLock.pop(); // thread cannot be null.
                }
-        thread.next = null;
-        thread.job = job;
-        thread.start();
+               // synchronize so that getThread can't sneak in between
+               // test for job == null and this.wait() in thread.run().
+               synchronized (thread) {
+                       thread.next = null;
+                       thread.job = job; 
+                       thread.notify();
+               }
                
                countLock.mightNotify();
                return thread;
@@ -196,19 +204,24 @@
             return job;
         }
                
-        public final synchronized void start() {
-            this.notify();
-        }
-               
         public final void run() {
             while (alive.state()) {
                 synchronized (this) {
                     while (alive.state() && job == null) {
+                                               // If getThread didn't synchronize 
(thread),
+                                               // it could sneak in here and change 
job and
+                                               // issue it's notify after the test 
but before
+                                               // the wait.
                         try {
-                            //There is no need to timeout this wait, getThread()
-                            //is the only way to get a thread, and it does
-                            //thread.start() which will awaken the thread, and
-                            //thread.die() also awakens the thread.
+                            // There is no need to timeout this wait,
+                                                       // so long as getThread() 
synchronizes.
+                                                       // getThread() is the only way 
to get a
+                                                       // thread.  It synchronizes 
(thread), then
+                                                       // changes thread.job, and 
only then does
+                                                       // thread.notify().  
thread.die() also
+                                                       // synchronizes, then changes
+                                                       // alive.state(), and only 
then does
+                                                       // thread.notify().
                             this.wait();
                         }
                         catch (InterruptedException e) {}
@@ -310,17 +323,21 @@
                // thread hasn't been removed yet.
                private int available = 0;
                
+               // take a snapshot
                synchronized void snap(CountSnap snap) {
                        snap.active = active;
                        snap.available = available;
                }
                
+               // free a thread, then take a snapshot.
                synchronized void snapFree(CountSnap snap) {
                        available++; // thread was already pushed onto stack.
                        snap.active = active;
                        snap.available = available;
                }
                
+               // maybe take a thread, then take a snapshot.
+               // return true if got a thread.
                synchronized boolean snapTake(CountSnap snap) {
                        boolean gotOne = false;
                        if (available >= 1) { // There is at least one on stack.

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

Reply via email to