Author: toad
Date: 2007-03-08 23:09:36 +0000 (Thu, 08 Mar 2007)
New Revision: 12045
Modified:
trunk/freenet/src/freenet/node/NodeClientCore.java
trunk/freenet/src/freenet/node/RequestHandler.java
trunk/freenet/src/freenet/node/RequestSender.java
Log:
Fix long-running minor routing bug relating to request coalescing: #902
Modified: trunk/freenet/src/freenet/node/NodeClientCore.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeClientCore.java 2007-03-08 21:22:57 UTC
(rev 12044)
+++ trunk/freenet/src/freenet/node/NodeClientCore.java 2007-03-08 23:09:36 UTC
(rev 12045)
@@ -318,8 +318,10 @@
}
RequestSender rs = (RequestSender)o;
boolean rejectedOverload = false;
+ short waitStatus = 0;
while(true) {
- if(rs.waitUntilStatusChange() && (!rejectedOverload)) {
+ waitStatus = rs.waitUntilStatusChange(waitStatus);
+ if((!rejectedOverload) && (waitStatus &
RequestSender.WAIT_REJECTED_OVERLOAD) != 0) {
// See below; inserts count both
requestStarters.throttleWindow.rejectedOverload();
rejectedOverload = true;
@@ -416,8 +418,10 @@
}
RequestSender rs = (RequestSender)o;
boolean rejectedOverload = false;
+ short waitStatus = 0;
while(true) {
- if(rs.waitUntilStatusChange() && (!rejectedOverload)) {
+ waitStatus = rs.waitUntilStatusChange(waitStatus);
+ if((!rejectedOverload) && (waitStatus &
RequestSender.WAIT_REJECTED_OVERLOAD) != 0) {
requestStarters.throttleWindow.rejectedOverload();
rejectedOverload = true;
}
Modified: trunk/freenet/src/freenet/node/RequestHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestHandler.java 2007-03-08 21:22:57 UTC
(rev 12044)
+++ trunk/freenet/src/freenet/node/RequestHandler.java 2007-03-08 23:09:36 UTC
(rev 12045)
@@ -104,15 +104,18 @@
boolean shouldHaveStartedTransfer = false;
+ short waitStatus = 0;
+
while(true) {
- if(rs.waitUntilStatusChange()) {
+ waitStatus = rs.waitUntilStatusChange(waitStatus);
+ if((waitStatus & RequestSender.WAIT_REJECTED_OVERLOAD) != 0) {
// Forward RejectedOverload
Message msg = DMT.createFNPRejectedOverload(uid, false);
source.sendAsync(msg, null, 0, null);
}
- if(rs.transferStarted()) {
+ if((waitStatus & RequestSender.WAIT_TRANSFERRING_DATA) != 0) {
// Is a CHK.
Message df = DMT.createFNPCHKDataFound(uid, rs.getHeaders());
source.send(df, null);
Modified: trunk/freenet/src/freenet/node/RequestSender.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestSender.java 2007-03-08 21:22:57 UTC
(rev 12044)
+++ trunk/freenet/src/freenet/node/RequestSender.java 2007-03-08 23:09:36 UTC
(rev 12045)
@@ -479,25 +479,40 @@
return prb != null;
}
- boolean hadROLastTimeWaited;
- boolean prbWasNonNull;
+ // these are bit-masks
+ static final short WAIT_REJECTED_OVERLOAD = 1;
+ static final short WAIT_TRANSFERRING_DATA = 2;
+ static final short WAIT_FINISHED = 4;
+ static final short WAIT_ALL =
+ WAIT_REJECTED_OVERLOAD | WAIT_TRANSFERRING_DATA | WAIT_FINISHED;
+
/**
- * Wait until either the transfer has started or we have a
- * terminal status code.
- * @return True if we got a RejectedOverload.
+ * Wait until either the transfer has started, we receive a
+ * RejectedOverload, or we get a terminal status code.
+ * @param mask Bitmask indicating what NOT to wait for i.e. the situation
when this function
+ * exited last time (see WAIT_ constants above). Bits can also be set true
even though they
+ * were not valid, to indicate that the caller doesn't care about that bit.
+ * If zero, function will throw an IllegalArgumentException.
+ * @return Bitmask indicating present situation. Can be fed back to this
function,
+ * if nonzero.
*/
- public synchronized boolean waitUntilStatusChange() {
+ public synchronized short waitUntilStatusChange(short mask) {
+ if(mask == WAIT_ALL) throw new IllegalArgumentException("Cannot ignore
all!");
while(true) {
- if((!hadROLastTimeWaited) && hasForwardedRejectedOverload) {
- hadROLastTimeWaited = true;
- return true;
- }
- if((!prbWasNonNull) && (prb != null)) {
- prbWasNonNull = true;
- return false;
- }
- if(status != NOT_FINISHED) return false;
+ short current = mask; // If any bits are set already, we ignore
those states.
+
+ if(hasForwardedRejectedOverload)
+ current |= WAIT_REJECTED_OVERLOAD;
+
+ if(prb != null)
+ current |= WAIT_TRANSFERRING_DATA;
+
+ if(status != NOT_FINISHED)
+ current |= WAIT_FINISHED;
+
+ if(current != mask) return current;
+
try {
wait(10000);
} catch (InterruptedException e) {