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;
+ }
+ }
+
+ }
+
}