#1451 File.mmap doesn't close files

dsav Fri 18 Mar 2011

The following script crashes with "Too many open files" on 1002 iteration on my machine:

for (Int i := 0; i < Int.maxVal; ++i) {
  echo("Iteration $i")
  Buf b := File.make(`filepath`).mmap    
  Str? s := null
  try {
    while (b.more) {
      Int? t := b.read
    }
  } finally {
    b.close
  }
}

Looks like a bug. When MappedByteBuffer is created, respective RandomAccessFile is not closed. The following patch fixed the bug for me:

diff -r 97613a391200 src/sys/java/fan/sys/LocalFile.java
--- a/src/sys/java/fan/sys/LocalFile.java	Fri Mar 18 18:52:58 2011 +0600
+++ b/src/sys/java/fan/sys/LocalFile.java	Fri Mar 18 19:28:10 2011 +0600
@@ -339,12 +339,22 @@
       // if size is null, use file size
       if (size == null) size = size();
 
-      // traverse the various Java APIs
-      RandomAccessFile fp = new RandomAccessFile(file, rw);
-      FileChannel chan = fp.getChannel();
-      MappedByteBuffer mmap = chan.map(mm, pos, size.longValue());
+      RandomAccessFile fp = null;
+      FileChannel chan = null;
 
-      return new MmapBuf(this, mmap);
+      try {
+        // traverse the various Java APIs
+        fp = new RandomAccessFile(file, rw);
+        chan = fp.getChannel();
+        MappedByteBuffer mmap = chan.map(mm, pos, size.longValue());
+
+        return new MmapBuf(this, mmap);
+      }
+      finally
+      {
+        if (null != chan) chan.close();
+        if (null != fp) fp.close();
+      }
     }
     catch (java.io.IOException e)
     {

brian Sat 19 Mar 2011

The old code didn't cause a problem on my Windows box, so I can't reproduce it. But I pushed the change - seems safe to close the FileChannel. The Javadoc for FileChannel.mmap says:

A mapping, once established, is not dependent upon the file channel that 
was used to create it. Closing the channel, in particular, has no effect 
upon the validity of the mapping.

changeset

Thanks for reporting and providing fix.

Login or Signup to reply.