Author: toad
Date: 2006-12-14 21:25:15 +0000 (Thu, 14 Dec 2006)
New Revision: 11412

Modified:
   trunk/freenet/src/freenet/client/async/SingleFileInserter.java
   trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
   trunk/freenet/src/freenet/support/api/BucketFactory.java
   trunk/freenet/src/freenet/support/io/BucketTools.java
   
trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucketFactory.java
   
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java
   trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
Log:
API fix: BucketTools.freeBucket() sucks, delete it.
Also fix a memory leak in PersistentTempBucketFactory (the to-free list would 
never stop growing, despite the buckets being freed every so often).

Modified: trunk/freenet/src/freenet/client/async/SingleFileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileInserter.java      
2006-12-14 21:19:27 UTC (rev 11411)
+++ trunk/freenet/src/freenet/client/async/SingleFileInserter.java      
2006-12-14 21:25:15 UTC (rev 11412)
@@ -165,12 +165,12 @@
                                                bestCodec = comp;
                                                data = result;
                                                if(bestCompressedData != null)
-                                                       
ctx.bf.freeBucket(bestCompressedData);
+                                                       
bestCompressedData.free();
                                                bestCompressedData = data;
                                                break;
                                        }
                                        if((bestCompressedData != null) && 
(result.size() <  bestCompressedData.size())) {
-                                               
ctx.bf.freeBucket(bestCompressedData);
+                                               bestCompressedData.free();
                                                bestCompressedData = result;
                                                data = result;
                                                bestCodec = comp;

Modified: trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java        
2006-12-14 21:19:27 UTC (rev 11411)
+++ trunk/freenet/src/freenet/client/async/SplitFileInserterSegment.java        
2006-12-14 21:25:15 UTC (rev 11412)
@@ -399,11 +399,7 @@
                synchronized(this) {
                        for(int i=0;i<dataBlockInserters.length;i++) {
                                if(dataBlockInserters[i] == null && 
dataBlocks[i] != null) {
-                                       try {
-                                               
parent.ctx.persistentBucketFactory.freeBucket(dataBlocks[i]);
-                                       } catch (IOException e) {
-                                               Logger.error(this, "Could not 
free "+dataBlocks[i]+" : "+e, e);
-                                       }
+                                       dataBlocks[i].free();
                                        dataBlocks[i] = null;
                                }
                        }
@@ -506,11 +502,7 @@
                                return blocksCompleted;
                        }
                        checkBlockInserters[x] = null;
-                       try {
-                               
parent.ctx.persistentBucketFactory.freeBucket(checkBlocks[x]);
-                       } catch (IOException e) {
-                               Logger.error(this, "Could not free 
"+checkBlocks[x]+" : "+e, e);
-                       }
+                       checkBlocks[x].free();
                        checkBlocks[x] = null;
                } else {
                        if(dataBlockInserters[x] == null) {
@@ -519,11 +511,7 @@
                        }
                        dataBlockInserters[x] = null;
                        if(encoded) {
-                               try {
-                                       
parent.ctx.persistentBucketFactory.freeBucket(dataBlocks[x]);
-                               } catch (IOException e) {
-                                       Logger.error(this, "Could not free 
"+dataBlocks[x]+" : "+e, e);
-                               }
+                               dataBlocks[x].free();
                                dataBlocks[x] = null;
                        }
                }

Modified: trunk/freenet/src/freenet/support/api/BucketFactory.java
===================================================================
--- trunk/freenet/src/freenet/support/api/BucketFactory.java    2006-12-14 
21:19:27 UTC (rev 11411)
+++ trunk/freenet/src/freenet/support/api/BucketFactory.java    2006-12-14 
21:25:15 UTC (rev 11412)
@@ -8,6 +8,5 @@

 public interface BucketFactory {
     public Bucket makeBucket(long size) throws IOException;
-    public void freeBucket(Bucket b) throws IOException;
 }


Modified: trunk/freenet/src/freenet/support/io/BucketTools.java
===================================================================
--- trunk/freenet/src/freenet/support/io/BucketTools.java       2006-12-14 
21:19:27 UTC (rev 11411)
+++ trunk/freenet/src/freenet/support/io/BucketTools.java       2006-12-14 
21:25:15 UTC (rev 11412)
@@ -164,16 +164,10 @@

                for (int i = 0; i < buckets.length; i++) {
                        // Make sure we free any temp buckets on exception
-                       try {
-                               if (buckets[i] != null) {
-                                       bf.freeBucket(buckets[i]);
-                               }
-                               buckets[i] = null;
-                       } catch (IOException e) {
-                               if (firstIoe == null) {
-                                       firstIoe = e;
-                               }
+                       if (buckets[i] != null) {
+                               buckets[i].free();
                        }
+                       buckets[i] = null;
                }

                if (firstIoe != null) {

Modified: 
trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucketFactory.java
===================================================================
--- 
trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucketFactory.java
   2006-12-14 21:19:27 UTC (rev 11411)
+++ 
trunk/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucketFactory.java
   2006-12-14 21:25:15 UTC (rev 11412)
@@ -25,8 +25,4 @@
        public Bucket makeBucket(long size) throws IOException {
                return new 
PaddedEphemerallyEncryptedBucket(baseFactory.makeBucket(size), minSize, random, 
true);
        }
-
-       public void freeBucket(Bucket b) throws IOException {
-               baseFactory.freeBucket(b);
-       }
 }

Modified: 
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java
===================================================================
--- 
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java  
    2006-12-14 21:19:27 UTC (rev 11411)
+++ 
trunk/freenet/src/freenet/support/io/PersistentEncryptedTempBucketFactory.java  
    2006-12-14 21:25:15 UTC (rev 11412)
@@ -20,8 +20,4 @@
        public Bucket makeBucket(long size) throws IOException {
                return bf.makeEncryptedBucket();
        }
-
-       public void freeBucket(Bucket b) throws IOException {
-               bf.freeBucket(b);
-       }
 }

Modified: trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
===================================================================
--- trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java       
2006-12-14 21:19:27 UTC (rev 11411)
+++ trunk/freenet/src/freenet/support/io/PersistentTempBucketFactory.java       
2006-12-14 21:25:15 UTC (rev 11412)
@@ -5,6 +5,8 @@

 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -81,19 +83,23 @@
                if(mustExist && !f.exists())
                        throw new IOException("File does not exist (deleted?): 
"+f);
                Bucket b = new FileBucket(f, false, false, false, true);
-               originalFiles.remove(f);
+               synchronized(this) {
+                       originalFiles.remove(f);
+               }
                return b;
        }

        public void register(File file) {
-               originalFiles.remove(file);
+               synchronized(this) {
+                       originalFiles.remove(file);
+               }
        }

        /**
         * Called when boot-up is complete.
         * Deletes any old temp files still unclaimed.
         */
-       public void completedInit() {
+       public synchronized void completedInit() {
                Iterator i = originalFiles.iterator();
                while(i.hasNext()) {
                        File f = (File) (i.next());
@@ -101,18 +107,18 @@
                }
        }

-       public Bucket makeRawBucket(long size) throws IOException {
+       private Bucket makeRawBucket(long size) throws IOException {
                return new FileBucket(fg.makeRandomFilename(), false, false, 
false, true);
        }

        public Bucket makeBucket(long size) throws IOException {
                Bucket b = makeRawBucket(size);
-               return new PaddedEphemerallyEncryptedBucket(b, 1024, rand, 
false);
+               return new DelayedFreeBucket(new 
PaddedEphemerallyEncryptedBucket(b, 1024, rand, false));
        }

        public Bucket makeEncryptedBucket() throws IOException {
                Bucket b = makeRawBucket(-1);
-               return new PaddedEphemerallyEncryptedBucket(b, 1024, rand, 
false);
+               return new DelayedFreeBucket(new 
PaddedEphemerallyEncryptedBucket(b, 1024, rand, false));
        }

        /**
@@ -125,13 +131,13 @@
         */
        public Bucket registerEncryptedBucket(String filename, byte[] key, long 
len) throws IOException {
                Bucket fileBucket = register(filename, len > 0);
-               return new PaddedEphemerallyEncryptedBucket(fileBucket, 1024, 
len, key, rand);
+               return new DelayedFreeBucket(new 
PaddedEphemerallyEncryptedBucket(fileBucket, 1024, len, key, rand));
        }

        /**
         * Free an allocated bucket, but only after the change has been written 
to disk.
         */
-       public void freeBucket(Bucket b) throws IOException {
+       public void delayedFreeBucket(Bucket b) {
                synchronized(this) {
                        bucketsToFree.add(b);
                }
@@ -139,11 +145,59 @@

        public Bucket[] grabBucketsToFree() {
                synchronized(this) {
-                       return (Bucket[]) bucketsToFree.toArray(new 
Bucket[bucketsToFree.size()]);
+                       Bucket[] toFree = (Bucket[]) bucketsToFree.toArray(new 
Bucket[bucketsToFree.size()]);
+                       bucketsToFree.clear();
+                       return toFree;
                }
        }

        public File getDir() {
                return dir;
        }
+       
+       public class DelayedFreeBucket implements Bucket {
+
+               Bucket bucket;
+               boolean freed;
+               
+               public DelayedFreeBucket(PaddedEphemerallyEncryptedBucket 
bucket) {
+                       this.bucket = bucket;
+               }
+
+               public OutputStream getOutputStream() throws IOException {
+                       if(freed) throw new IOException("Already freed");
+                       return bucket.getOutputStream();
+               }
+
+               public InputStream getInputStream() throws IOException {
+                       if(freed) throw new IOException("Already freed");
+                       return bucket.getInputStream();
+               }
+
+               public String getName() {
+                       return bucket.getName();
+               }
+
+               public long size() {
+                       return bucket.size();
+               }
+
+               public boolean isReadOnly() {
+                       return bucket.isReadOnly();
+               }
+
+               public void setReadOnly() {
+                       bucket.setReadOnly();
+               }
+
+               public void free() {
+                       synchronized(this) { // mutex on just this method; make 
a separate lock if necessary to lock the above
+                               if(freed) return;
+                               delayedFreeBucket(bucket);
+                               freed = true;
+                       }
+               }
+
+       }
+
 }


Reply via email to