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