r26859 - trunk/freenet/src/freenet/client/async
[email protected] Wed, 15 Apr 2009 22:31:49 +0000
| Newsgroups | gmane.network.freenet.cvs |
|---|---|
| Message-ID | <[email protected]> |
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) {