Author: toad
Date: 2005-12-06 14:23:03 +0000 (Tue, 06 Dec 2005)
New Revision: 7680

Modified:
   trunk/freenet/src/freenet/node/InsertSender.java
   trunk/freenet/src/freenet/node/Version.java
Log:
278: (mandatory)
Various debugging in the completion mechanism on inserts.
Don't return until either all the transfers have completed, or we have timed 
out.
(We were only waiting until all the nodes had sent us completions; in some 
circumstances nodes can send us completions when the data hasn't been 
transferred yet; this may not be sensible, but clearly we don't want to return 
early just because nodes accidentally or maliciously sent us a completion 
notice too soon!).


Modified: trunk/freenet/src/freenet/node/InsertSender.java
===================================================================
--- trunk/freenet/src/freenet/node/InsertSender.java    2005-12-06 13:36:59 UTC 
(rev 7679)
+++ trunk/freenet/src/freenet/node/InsertSender.java    2005-12-06 14:23:03 UTC 
(rev 7680)
@@ -58,6 +58,12 @@
                        synchronized(nodesWaitingForCompletion) {
                                nodesWaitingForCompletion.notifyAll();
                        }
+                       if(!success) {
+                               synchronized(InsertSender.this) {
+                                       transferTimedOut = true;
+                                       InsertSender.this.notifyAll();
+                               }
+                       }
                }

                void completedTransfer(boolean success) {
@@ -621,21 +627,38 @@
                                                // Added another one
                                                Logger.minor(this, "Looping 
(mf==null): waiters="+waiters.length+" but 
waiting="+nodesWaitingForCompletion.size());
                                        }
-                                       // All done!
-                                       Logger.minor(this, "Completed, 
status="+getStatusString()+", nothing left to wait for.");
-                                       synchronized(InsertSender.this) {
-                                               allTransfersCompleted = true;
-                                               InsertSender.this.notifyAll();
+                                       if(waitForCompletedTransfers(waiters, 
timeout, noTimeLeft)) {
+                                               synchronized(InsertSender.this) 
{
+                                                       allTransfersCompleted = 
true;
+                                                       
InsertSender.this.notifyAll();
+                                               }
+                                               return;
                                        }
-                                       return;
-                               }
-                               synchronized(nodesWaitingForCompletion) {
-                                       try {
-                                               
nodesWaitingForCompletion.wait(timeout);
-                                       } catch (InterruptedException e) {
-                                               // Go back around the loop
+                                       if(timeout <= 0) {
+                                               for(int 
i=0;i<waiters.length;i++) {
+                                                       
if(!waiters[i].completedTransfer) {
+                                                               
waiters[i].completedTransfer(false);
+                                                       }
+                                               }
+                                               synchronized(InsertSender.this) 
{
+                                                       allTransfersCompleted = 
true;
+                                                       
InsertSender.this.notifyAll();
+                                               }
+                                               return;
                                        }
+                                       // Otherwise, not finished, go back 
around loop
+                                       continue;
+                               } else {
+                                       // Still waiting for request 
completion, so more may be added
+                                       synchronized(nodesWaitingForCompletion) 
{
+                                               try {
+                                                       
nodesWaitingForCompletion.wait(timeout);
+                                               } catch (InterruptedException 
e) {
+                                                       // Go back around the 
loop
+                                               }
+                                       }
                                }
+                               continue;
                        } else {
                                Message m;
                                try {
@@ -656,19 +679,13 @@
                                                        
waiters[i].completed(false, !anyTimedOut);
                                                        if(anyTimedOut) {
                                                                
synchronized(InsertSender.this) {
-                                                                       
transferTimedOut = true;
-                                                                       
InsertSender.this.notifyAll();
-                                                               }
-                                                       }
-                                                       processed = true;
-                                                       
if(waiters[i].completedTransfer) {
-                                                               
if(!waiters[i].transferSucceeded) {
-                                                                       
synchronized(InsertSender.this) {
+                                                                       
if(!transferTimedOut) {
                                                                                
transferTimedOut = true;
                                                                                
InsertSender.this.notifyAll();
                                                                        }
                                                                }
                                                        }
+                                                       processed = true;
                                                        break;
                                                }
                                        }
@@ -686,6 +703,8 @@
                                                for(int 
i=0;i<waiters.length;i++) {
                                                        
if(!waiters[i].receivedCompletionNotice)
                                                                
waiters[i].completed(false, false);
+                                                       
if(!waiters[i].completedTransfer)
+                                                               
waiters[i].completedTransfer(false);
                                                }
                                                synchronized(InsertSender.this) 
{
                                                        transferTimedOut = true;
@@ -698,7 +717,47 @@
                        }
                }
                }
-               
+
+               /** @return True if all transfers have completed, false 
otherwise. */
+               private boolean waitForCompletedTransfers(AwaitingCompletion[] 
waiters, int timeout, boolean noTimeLeft) {
+                       // MAYBE all done
+                       boolean completedTransfers = true;
+                       synchronized(nodesWaitingForCompletion) {
+                               for(int i=0;i<waiters.length;i++) {
+                                       if(!waiters[i].completedTransfer) {
+                                               completedTransfers = false;
+                                               break;
+                                       }
+                               }
+                               if(!completedTransfers) {
+                                       try {
+                                               if(!noTimeLeft) {
+                                                       
nodesWaitingForCompletion.wait(timeout);
+                                               } else {
+                                                       // Timed out
+                                               }
+                                               for(int 
i=0;i<waiters.length;i++) {
+                                                       
if(!waiters[i].completedTransfer) {
+                                                               
completedTransfers = false;
+                                                               break;
+                                                       }
+                                               }
+                                       } catch (InterruptedException e) {
+                                               // Ignore
+                                       }
+                               }
+                       }
+                       if(completedTransfers) {
+                               // All done!
+                               Logger.minor(this, "Completed, 
status="+getStatusString()+", nothing left to wait for.");
+                               synchronized(InsertSender.this) {
+                                       allTransfersCompleted = true;
+                                       InsertSender.this.notifyAll();
+                               }
+                               return true;
+                       } else return false;
+               }
+
                public String toString() {
                        return super.toString()+" for "+uid;
                }

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2005-12-06 13:36:59 UTC (rev 
7679)
+++ trunk/freenet/src/freenet/node/Version.java 2005-12-06 14:23:03 UTC (rev 
7680)
@@ -20,10 +20,10 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       public static final int buildNumber = 277;
+       public static final int buildNumber = 278;

        /** Oldest build of Fred we will talk to */
-       public static final int lastGoodBuild = 277;
+       public static final int lastGoodBuild = 278;

        /** The highest reported build of fred */
        public static int highestSeenBuild = buildNumber;


Reply via email to