Author: toad
Date: 2008-02-18 23:15:00 +0000 (Mon, 18 Feb 2008)
New Revision: 18057

Modified:
   trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
   trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
Log:
If we add a key to a subsegment after the subsegment has itself been scheduled, 
the CRS will not know that we want that key (for backdoor coalescing).
Hence backdoor coalescing is completely broken in two cases: 1) blocks taken 
off the cooldown queue, and 2) retries.

Modified: trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2008-02-18 22:52:00 UTC (rev 18056)
+++ trunk/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2008-02-18 23:15:00 UTC (rev 18057)
@@ -267,7 +267,11 @@
                starter.wakeUp();
        }

-       private void addPendingKey(ClientKey key, SendableGet getter) {
+       /**
+        * Register a pending key to an already-registered request. This is 
necessary if we've
+        * already registered a SendableGet, but we later add some more keys to 
it.
+        */
+       void addPendingKey(ClientKey key, SendableGet getter) {
                if(logMINOR)
                        Logger.minor(this, "Adding pending key "+key+" for 
"+getter);
                Key nodeKey = key.getNodeKey();
@@ -596,6 +600,7 @@
        }

        public void tripPendingKey(final KeyBlock block) {
+               if(logMINOR) Logger.minor(this, 
"tripPendingKey("+block.getKey()+")");
                if(offeredKeys != null) {
                        for(int i=0;i<offeredKeys.length;i++) {
                                offeredKeys[i].remove(block.getKey());
@@ -620,6 +625,7 @@
                if(gets == null) return;
                Runnable r = new Runnable() {
                        public void run() {
+                               if(logMINOR) Logger.minor(this, "Running 
callbacks off-thread for "+block.getKey());
                                for(int i=0;i<gets.length;i++) {
                                        gets[i].onGotKey(key, block, 
ClientRequestScheduler.this);
                                }

Modified: trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java      
2008-02-18 22:52:00 UTC (rev 18056)
+++ trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java      
2008-02-18 23:15:00 UTC (rev 18057)
@@ -254,11 +254,13 @@
                if(logMINOR) Logger.minor(this, "Adding block "+blockNo+" to 
"+this+" dontSchedule="+dontSchedule);
                if(blockNo < 0) throw new IllegalArgumentException();
                Integer i = new Integer(blockNo);
+               
+               boolean schedule = true;
                synchronized(this) {
                        if(cancelled)
                                throw new IllegalStateException("Adding block 
"+blockNo+" to already cancelled "+this);
                        blockNums.add(i);
-                       if(dontSchedule) return;
+                       if(dontSchedule) schedule = false;
                        /**
                         * Race condition:
                         * 
@@ -272,12 +274,15 @@
                         * So what we do here is simply check whether we are 
registered, instead of 
                         * checking whether blockNums.size() > 1 as we used to.
                         */
-                       if(getParentGrabArray() != null) {
+                       if(schedule && getParentGrabArray() != null) {
                                if(logMINOR) Logger.minor(this, "Already 
registered, not scheduling: "+blockNums.size()+" : "+blockNums);
-                               return;
+                               schedule = false;
                        }
                }
-               if(!dontSchedule) schedule();
+               if(schedule) schedule();
+               else
+                       // Already scheduled, however this key may not be 
registered.
+                       
getScheduler().addPendingKey(segment.getBlockKey(blockNo), this);
        }

        public String toString() {


Reply via email to