Author: toad
Date: 2006-03-03 18:47:25 +0000 (Fri, 03 Mar 2006)
New Revision: 8146

Modified:
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/node/fcp/ClientGet.java
   trunk/freenet/src/freenet/node/fcp/ClientPut.java
Log:
484:
Bugfix for direct ClientGet's, and add synchronization to avoid races.

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-03-03 18:14:37 UTC (rev 
8145)
+++ trunk/freenet/src/freenet/node/Version.java 2006-03-03 18:47:25 UTC (rev 
8146)
@@ -20,7 +20,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 483;
+       private static final int buildNumber = 484;

        /** Oldest build of Fred we will talk to */
        private static final int lastGoodBuild = 475;

Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-03-03 18:14:37 UTC 
(rev 8145)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-03-03 18:47:25 UTC 
(rev 8146)
@@ -177,70 +177,55 @@
        }

        public void onSuccess(FetchResult result, ClientGetter state) {
-               progressPending = null;
-               FCPMessage msg = new DataFoundMessage(result, identifier);
                Bucket data = result.asBucket();
-               this.foundDataLength = data.size();
-               this.foundDataMimeType = result.getMimeType();
-               this.succeeded = true;
-               finished = true;
-               if(returnType == ClientGetMessage.RETURN_TYPE_DIRECT) {
-                       // Send all the data at once
-                       // FIXME there should be other options
-                       trySendDataFoundOrGetFailed();
-                       AllDataMessage m = new AllDataMessage(data, identifier);
-                       if(persistenceType == PERSIST_CONNECTION)
-                               m.setFreeOnSent();
-                       trySendAllDataMessage(m);
-                       finish();
-                       return;
-               } else if(returnType == ClientGetMessage.RETURN_TYPE_NONE) {
-                       // Do nothing
-                       trySendDataFoundOrGetFailed();
-                       data.free();
-                       finish();
-                       return;
-               } else if(returnType == ClientGetMessage.RETURN_TYPE_DISK) {
-                       // Write to temp file, then rename over filename
-                       FileOutputStream fos;
-                       try {
-                               fos = new FileOutputStream(tempFile);
-                       } catch (FileNotFoundException e) {
-                               postFetchProtocolErrorMessage = new 
ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_WRITE_FILE, false, null, 
identifier);
+               boolean dontFree = false;
+               // FIXME I don't think this is a problem in this case...? (Disk 
write while locked..)
+               synchronized(this) {
+                       if(returnType == ClientGetMessage.RETURN_TYPE_DIRECT) {
+                               // Send all the data at once
+                               // FIXME there should be other options
                                trySendDataFoundOrGetFailed();
-                               data.free();
-                               finish();
-                               return;
-                       }
-                       try {
-                               BucketTools.copyTo(data, fos, data.size());
-                       } catch (IOException e) {
-                               postFetchProtocolErrorMessage = new 
ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_WRITE_FILE, false, null, 
identifier);
-                               trySendDataFoundOrGetFailed();
-                               data.free();
+                               AllDataMessage m = new AllDataMessage(data, 
identifier);
+                               if(persistenceType == PERSIST_CONNECTION)
+                                       m.setFreeOnSent();
+                               dontFree = true;
+                               trySendAllDataMessage(m);
+                       } else if(returnType == 
ClientGetMessage.RETURN_TYPE_NONE) {
+                               // Do nothing
+                       } else if(returnType == 
ClientGetMessage.RETURN_TYPE_DISK) {
+                               // Write to temp file, then rename over filename
+                               FileOutputStream fos = null;
                                try {
-                                       fos.close();
-                               } catch (IOException e1) {
-                                       // Ignore
+                                       fos = new FileOutputStream(tempFile);
+                                       BucketTools.copyTo(data, fos, 
data.size());
+                                       if(!tempFile.renameTo(targetFile)) {
+                                               postFetchProtocolErrorMessage = 
new ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_RENAME_FILE, false, 
null, identifier);
+                                               trySendDataFoundOrGetFailed();
+                                               // Don't delete temp file, user 
might want it.
+                                       }
+                               } catch (FileNotFoundException e) {
+                                       postFetchProtocolErrorMessage = new 
ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_WRITE_FILE, false, null, 
identifier);
+                               } catch (IOException e) {
+                                       postFetchProtocolErrorMessage = new 
ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_WRITE_FILE, false, null, 
identifier);
                                }
-                               finish();
-                               return;
+                               try {
+                                       if(fos != null)
+                                               fos.close();
+                               } catch (IOException e) {
+                                       Logger.error(this, "Caught "+e+" 
closing file "+tempFile, e);
+                               }
                        }
-                       try {
-                               fos.close();
-                       } catch (IOException e) {
-                               Logger.error(this, "Caught "+e+" closing file 
"+tempFile, e);
-                       }
-                       if(!tempFile.renameTo(targetFile)) {
-                               postFetchProtocolErrorMessage = new 
ProtocolErrorMessage(ProtocolErrorMessage.COULD_NOT_RENAME_FILE, false, null, 
identifier);
-                               trySendDataFoundOrGetFailed();
-                               // Don't delete temp file, user might want it.
-                       }
-                       data.free();
-                       trySendDataFoundOrGetFailed();
-                       finish();
-                       return;
+                       progressPending = null;
+                       FCPMessage msg = new DataFoundMessage(result, 
identifier);
+                       this.foundDataLength = data.size();
+                       this.foundDataMimeType = result.getMimeType();
+                       this.succeeded = true;
+                       finished = true;
                }
+               trySendDataFoundOrGetFailed();
+               if(!dontFree)
+                       data.free();
+               finish();
        }

        private void trySendDataFoundOrGetFailed() {
@@ -296,9 +281,11 @@
        }

        public void onFailure(FetchException e, ClientGetter state) {
-               succeeded = false;
-               getFailedMessage = new GetFailedMessage(e, identifier);
-               finished = true;
+               synchronized(this) {
+                       succeeded = false;
+                       getFailedMessage = new GetFailedMessage(e, identifier);
+                       finished = true;
+               }
                Logger.minor(this, "Caught "+e, e);
                trySendDataFoundOrGetFailed();
                finish();
@@ -360,7 +347,7 @@

        // This is distinct from the ClientGetMessage code, as later on it will 
be radically
        // different (it can store detailed state).
-       public SimpleFieldSet getFieldSet() {
+       public synchronized SimpleFieldSet getFieldSet() {
                SimpleFieldSet fs = new SimpleFieldSet(true); // we will need 
multi-level later...
                fs.put("Type", "GET");
                fs.put("URI", uri.toString(false));

Modified: trunk/freenet/src/freenet/node/fcp/ClientPut.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPut.java   2006-03-03 18:14:37 UTC 
(rev 8145)
+++ trunk/freenet/src/freenet/node/fcp/ClientPut.java   2006-03-03 18:47:25 UTC 
(rev 8146)
@@ -114,17 +114,8 @@
                this.client = client2;
                origHandler = null;
                String mimeType = fs.get("Metadata.ContentType");
-                if(fs.get("GetCHKOnly").equalsIgnoreCase("true")){
-                       getCHKOnly = true;
-               }else{
-                       getCHKOnly = false;
-               }
-               boolean dontCompress;
-                if(fs.get("DontCompress").equalsIgnoreCase("true")){
-                       dontCompress = true;
-               }else{
-                       dontCompress = false;
-               }
+               getCHKOnly = Fields.stringToBool(fs.get("CHKOnly"), false);
+               boolean dontCompress = 
Fields.stringToBool(fs.get("DontCompress"), false);
                int maxRetries = Integer.parseInt(fs.get("MaxRetries"));
                clientToken = fs.get("ClientToken");
                fromDisk = true;
@@ -166,26 +157,32 @@
        }

        public void onSuccess(BaseClientPutter state) {
-               progressMessage = null;
-               succeeded = true;
-               finished = true;
+               synchronized(this) {
+                       progressMessage = null;
+                       succeeded = true;
+                       finished = true;
+               }
                trySendFinalMessage();
                block.getData().free();
                finish();
        }

        public void onFailure(InserterException e, BaseClientPutter state) {
-               finished = true;
-               putFailedMessage = new PutFailedMessage(e, identifier);
+               synchronized(this) {
+                       finished = true;
+                       putFailedMessage = new PutFailedMessage(e, identifier);
+               }
                trySendFinalMessage();
                block.getData().free();
                finish();
        }

        public void onGeneratedURI(FreenetURI uri, BaseClientPutter state) {
-               if(generatedURI != null && !uri.equals(generatedURI))
-                       Logger.error(this, "onGeneratedURI("+uri+","+state+") 
but already set generatedURI to "+generatedURI);
-               generatedURI = uri;
+               synchronized(this) {
+                       if(generatedURI != null && !uri.equals(generatedURI))
+                               Logger.error(this, 
"onGeneratedURI("+uri+","+state+") but already set generatedURI to 
"+generatedURI);
+                       generatedURI = uri;
+               }
                trySendGeneratedURIMessage();
        }

@@ -302,7 +299,7 @@
                fs.writeTo(w);
        }

-       public SimpleFieldSet getFieldSet() throws IOException {
+       public synchronized SimpleFieldSet getFieldSet() throws IOException {
                SimpleFieldSet fs = new SimpleFieldSet(true); // we will need 
multi-level later...
                fs.put("Type", "PUT");
                fs.put("URI", uri.toString(false));


Reply via email to