Author: toad
Date: 2009-04-15 22:31:48 +0000 (Wed, 15 Apr 2009)
New Revision: 26859

Modified:
   trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
   trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
Log:
possiblyRemoveFromParent: Tell the caller whether they need to call kill(). 
They need to do this outside of the lock.
Call kill() outside the lock, and move onFatalFailure outside the lock too.


Modified: trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java 
2009-04-15 22:21:35 UTC (rev 26858)
+++ trunk/freenet/src/freenet/client/async/SplitFileFetcherSegment.java 
2009-04-15 22:31:48 UTC (rev 26859)
@@ -848,8 +848,10 @@
                        container.store(this);
                if(allFailed)
                        fail(new FetchException(FetchException.SPLITFILE_ERROR, 
errors), container, context, false);
-               else if(seg != null)
-                       seg.possiblyRemoveFromParent(container, context);
+               else if(seg != null) {
+                       if(seg.possiblyRemoveFromParent(container, context))
+                               seg.kill(container, context, true, true);
+               }
        }
        
        /** A request has failed non-fatally, so the block may be retried 
@@ -1454,11 +1456,13 @@
         * and then "NOT IN BLOOM FILTER" errors, or worse, false negatives.
         */
        public boolean onGotKey(Key key, KeyBlock block, ObjectContainer 
container, ClientContext context) {
-               ClientCHKBlock cb;
+               ClientCHKBlock cb = null;
                int blockNum;
-               Bucket data;
+               Bucket data = null;
                SplitFileFetcherSubSegment seg;
                short onSuccessResult = (short) -1;
+               boolean killSeg = false;
+               FetchException fatal = null;
                synchronized(this) {
                        if(finished || startedDecode || fetcherFinished) {
                                return false;
@@ -1474,7 +1478,7 @@
                                container.activate(seg, 1);
                        if(seg != null) {
                                seg.removeBlockNum(blockNum, container, false);
-                               seg.possiblyRemoveFromParent(container, 
context);
+                               killSeg = 
seg.possiblyRemoveFromParent(container, context);
                        }
                        for(int i=0;i<subSegments.size();i++) {
                                SplitFileFetcherSubSegment checkSeg = 
subSegments.get(i);
@@ -1491,15 +1495,15 @@
                        try {
                                cb = new ClientCHKBlock((CHKBlock)block, ckey);
                        } catch (CHKVerifyException e) {
-                               this.onFatalFailure(new 
FetchException(FetchException.BLOCK_DECODE_ERROR, e), blockNum, null, 
container, context);
-                               return false;
+                               fatal = new 
FetchException(FetchException.BLOCK_DECODE_ERROR, e);
                        }
+                       if(cb != null) {
                        data = extract(cb, blockNum, container, context);
                        if(data == null) {
                                if(logMINOR)
                                        Logger.minor(this, "Extract failed");
                                return false;
-                       }
+                       } else {
                        // This can be done safely inside the lock.
                        if(parent instanceof ClientGetter)
                                ((ClientGetter)parent).addKeyToBinaryBlob(cb, 
container, context);
@@ -1509,7 +1513,17 @@
                                // will only be removed from the Bloom filter 
ONCE!
                                onSuccessResult = onSuccessInner(data, 
blockNum, cb, container, context, seg);
                        }
+                       }
+                       }
                }
+               if(killSeg)
+                       seg.kill(container, context, true, true);
+               if(fatal != null) {
+                       this.onFatalFailure(fatal, blockNum, null, container, 
context);
+                       return false;
+               } else if(data == null) {
+                       return false; // Extract failed
+               } else { // cb != null
                if(!cb.isMetadata()) {
                        if(onSuccessResult != (short) -1)
                                finishOnSuccess(onSuccessResult, container, 
context);
@@ -1518,6 +1532,7 @@
                        onFatalFailure(new 
FetchException(FetchException.INVALID_METADATA, "Metadata where expected 
data"), blockNum, null, container, context);
                        return true;
                }
+               }
        }
        
        private int getBlockRetryCount(int blockNum) {

Modified: trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java      
2009-04-15 22:21:35 UTC (rev 26858)
+++ trunk/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java      
2009-04-15 22:31:48 UTC (rev 26859)
@@ -610,7 +610,14 @@
                return 
super.toString()+":"+retryCount+"/"+segment+'('+(blockNums == null ? "null" : 
String.valueOf(blockNums.size()))+"),tempid="+objectHash(); 
        }
 
-       public void possiblyRemoveFromParent(ObjectContainer container, 
ClientContext context) {
+       /**
+        * If there are no more blocks, cancel the SubSegment, remove it from 
the segment,
+        * and return true; the caller must call kill(,,true,true). Else return 
false.
+        * @param container
+        * @param context
+        * @return
+        */
+       public boolean possiblyRemoveFromParent(ObjectContainer container, 
ClientContext context) {
                if(persistent) {
                        container.activate(this, 1);
                        container.activate(segment, 1);
@@ -621,17 +628,17 @@
                synchronized(segment) {
                        if(!blockNums.isEmpty()) {
                                if(persistent) container.deactivate(blockNums, 
1);
-                               return;
+                               return false;
                        }
                        if(logMINOR)
                                Logger.minor(this, "Definitely removing from 
parent: "+this);
                        if(!segment.maybeRemoveSeg(this, container)) {
                                if(persistent) container.deactivate(blockNums, 
1);
-                               return;
+                               return false;
                        }
                        cancelled = true;
                }
-               kill(container, context, true, true);
+               return true;
        }
 
        public void onGotKey(Key key, KeyBlock block, ObjectContainer 
container, ClientContext context) {

_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to