Author: toad
Date: 2007-09-10 23:06:21 +0000 (Mon, 10 Sep 2007)
New Revision: 15125

Modified:
   trunk/freenet/src/freenet/client/async/USKFetcher.java
Log:
Run schedule's on separate thread to prevent infinite recursion when fetching 
USKs when we have many editions in the store

Modified: trunk/freenet/src/freenet/client/async/USKFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKFetcher.java      2007-09-10 
23:00:44 UTC (rev 15124)
+++ trunk/freenet/src/freenet/client/async/USKFetcher.java      2007-09-10 
23:06:21 UTC (rev 15125)
@@ -303,7 +303,7 @@
        void onSuccess(USKAttempt att, boolean dontUpdate, ClientSSKBlock 
block) {
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
                LinkedList l = null;
-               long lastEd = uskManager.lookup(origUSK);
+               final long lastEd = uskManager.lookup(origUSK);
                synchronized(this) {
                        runningAttempts.remove(att);
                        long curLatest = att.number;
@@ -340,21 +340,27 @@
                        cancelBefore(curLatest);
                }
                if(l == null) return;
+               final LinkedList toSched = l;
                // If we schedule them here, we don't get icky recursion 
problems.
-               else if(!cancelled) {
-                       for(Iterator i=l.iterator();i.hasNext();) {
-                               // We may be called recursively through 
onSuccess().
-                               // So don't start obsolete requests.
-                               USKAttempt a = (USKAttempt) i.next();
-                               lastEd = uskManager.lookup(origUSK);
-                               if((lastEd <= a.number) && !a.cancelled)
-                                       a.schedule();
-                               else {
-                                       synchronized(this) {
-                                               runningAttempts.remove(a);
+               if(!cancelled) {
+                       ctx.executor.execute(new Runnable() {
+                               public void run() {
+                                       long last = lastEd;
+                                       for(Iterator 
i=toSched.iterator();i.hasNext();) {
+                                               // We may be called recursively 
through onSuccess().
+                                               // So don't start obsolete 
requests.
+                                               USKAttempt a = (USKAttempt) 
i.next();
+                                               last = 
uskManager.lookup(origUSK);
+                                               if((last <= a.number) && 
!a.cancelled)
+                                                       a.schedule();
+                                               else {
+                                                       synchronized(this) {
+                                                               
runningAttempts.remove(a);
+                                                       }
+                                               }
                                        }
                                }
-                       }
+                       }, "USK scheduler"); // Run on separate thread because 
otherwise can get loooong recursions
                }
        }



Reply via email to