// line 1562 of https://github.com/freenet/fred/blob/3fcc2d1b3a0d5ccbeb73928d6b267440e5b4c17b/src/freenet/node/RequestSender.java#L1 private void finish(int code, PeerNode next, boolean fromOfferedKey) { if(logMINOR) Logger.minor(this, "finish("+code+ ") on "+this+" from "+next); boolean doOpennet; synchronized(this) { if(status != NOT_FINISHED) { if(logMINOR) Logger.minor(this, "Status already set to "+status+" - returning on "+this+" would be setting "+code+" from "+next); if(next != null) next.noLongerRoutingTo(origTag, fromOfferedKey); return; } doOpennet = code == SUCCESS && !(fromOfferedKey || isSSK); if(doOpennet) origTag.waitingForOpennet(next); // Call this first so we don't unlock. if(next != null) next.noLongerRoutingTo(origTag, fromOfferedKey); // After calling both, THEN tell handler. status = code; if(status == SUCCESS) successFrom = next; notifyAll(); } boolean shouldUnlock = doOpennet && next != null; if(status == SUCCESS) { if((!isSSK) && transferTime > 0 && logMINOR) { long timeTaken = System.currentTimeMillis() - startTime; synchronized(avgTimeTaken) { avgTimeTaken.report(timeTaken); avgTimeTakenTransfer.report(transferTime); if(logMINOR) Logger.minor(this, "Successful CHK request took "+timeTaken+" average "+avgTimeTaken); if(logMINOR) Logger.minor(this, "Successful CHK request transfer "+transferTime+" average "+avgTimeTakenTransfer); if(logMINOR) Logger.minor(this, "Search phase: median "+(avgTimeTaken.currentValue() - avgTimeTakenTransfer.currentValue())+"ms, mean "+(avgTimeTaken.meanValue() - avgTimeTakenTransfer.meanValue())+"ms"); } } if(next != null) { next.onSuccess(false, isSSK); } // FIXME should this be called when fromOfferedKey?? node.nodeStats.requestCompleted(true, source != null, isSSK); fireRequestSenderFinished(code, fromOfferedKey); if(doOpennet) { if(finishOpennet(next)) shouldUnlock = false; } } else { node.nodeStats.requestCompleted(false, source != null, isSSK); fireRequestSenderFinished(code, fromOfferedKey); } if(shouldUnlock) next.noLongerRoutingTo(origTag, fromOfferedKey); synchronized(this) { opennetFinished = true; notifyAll(); } } AsyncMessageCallback finishOpennetOnAck(final PeerNode next) { return new AsyncMessageCallback() { private boolean completed; @Override public void sent() { // Ignore } @Override public void acknowledged() { synchronized(this) { if(completed) return; completed = true; } origTag.finishedWaitingForOpennet(next); } @Override public void disconnected() { synchronized(this) { if(completed) return; completed = true; } origTag.finishedWaitingForOpennet(next); } @Override public void fatalError() { synchronized(this) { if(completed) return; completed = true; } origTag.finishedWaitingForOpennet(next); } }; }