Index: modules/quercus/src/com/caucho/quercus/lib/file/FileInput.java =================================================================== --- modules/quercus/src/com/caucho/quercus/lib/file/FileInput.java (revision 3290) +++ modules/quercus/src/com/caucho/quercus/lib/file/FileInput.java (working copy) @@ -33,6 +33,7 @@ import com.caucho.quercus.env.Value; import com.caucho.vfs.FilePath; import com.caucho.vfs.Path; +import com.caucho.vfs.ReadStream; import java.io.File; import java.io.IOException; @@ -50,8 +51,9 @@ private Env _env; private Path _path; + private FileLock _fileLock; - private RandomAccessFile _randomAccessFile; + private FileChannel _fileChannel; public FileInput(Env env, Path path) throws IOException @@ -123,24 +125,26 @@ if (! (getPath() instanceof FilePath)) return true; - try { - File file = ((FilePath) getPath()).getFile(); + if (!shared) { + // Invalid request for an exclusive "write" lock on a read only stream. - if (_randomAccessFile == null) { - _randomAccessFile = new RandomAccessFile(file, "rw"); + return true; + } + + try { + if (_fileChannel == null) { + _fileChannel = FilePath.getFileChannel((ReadStream) getInputStream()); } - FileChannel fileChannel = _randomAccessFile.getChannel(); - if (block) - _fileLock = fileChannel.lock(0, Long.MAX_VALUE, shared); + _fileLock = _fileChannel.lock(0, Long.MAX_VALUE, true); else - _fileLock = fileChannel.tryLock(0, Long.MAX_VALUE, shared); + _fileLock = _fileChannel.tryLock(0, Long.MAX_VALUE, true); return _fileLock != null; } catch (Exception e) { log.log(Level.FINE, e.toString(), e); - + return false; } } @@ -153,7 +157,7 @@ try { FileLock lock = _fileLock; _fileLock = null; - + if (lock != null) { lock.release(); @@ -162,6 +166,7 @@ return true; } catch (IOException e) { + log.log(Level.FINE, e.toString(), e); return false; } } @@ -173,28 +178,12 @@ public void close() { - try { - _env.removeClose(this); - - FileLock lock = _fileLock; - _fileLock = null; - - if (lock != null) - lock.release(); - } catch (IOException e) { - log.log(Level.FINE, e.toString(), e); - } - - try { - RandomAccessFile file = _randomAccessFile; - _randomAccessFile = null; - - if (file != null) - file.close(); - } catch (IOException e) { - log.log(Level.FINE, e.toString(), e); - } - + _env.removeClose(this); + + unlock(); + + _fileChannel = null; + super.close(); } Index: modules/quercus/src/com/caucho/quercus/lib/file/FileOutput.java =================================================================== --- modules/quercus/src/com/caucho/quercus/lib/file/FileOutput.java (revision 3290) +++ modules/quercus/src/com/caucho/quercus/lib/file/FileOutput.java (working copy) @@ -56,8 +56,9 @@ private Path _path; private WriteStream _os; private long _offset; + private FileLock _fileLock; - private RandomAccessFile _randomAccessFile; + private FileChannel _fileChannel; public FileOutput(Env env, Path path) throws IOException @@ -160,9 +161,13 @@ */ public void close() { + _env.removeClose(this); + + unlock(); + + _fileChannel = null; + try { - _env.removeClose(this); - WriteStream os = _os; _os = null; @@ -171,26 +176,6 @@ } catch (IOException e) { log.log(Level.FINE, e.toString(), e); } - - try { - FileLock lock = _fileLock; - _fileLock = null; - - if (lock != null) - lock.release(); - } catch (IOException e) { - log.log(Level.FINE, e.toString(), e); - } - - try { - RandomAccessFile file = _randomAccessFile; - _randomAccessFile = null; - - if (file != null) - file.close(); - } catch (IOException e) { - log.log(Level.FINE, e.toString(), e); - } } /** @@ -201,19 +186,21 @@ if (! (getPath() instanceof FilePath)) return true; - try { - File file = ((FilePath) getPath()).getFile(); + if (shared) { + // Invalid request for a shared "read" lock on a write only stream. - if (_randomAccessFile == null) { - _randomAccessFile = new RandomAccessFile(file, "rw"); + return true; + } + + try { + if (_fileChannel == null) { + _fileChannel = FilePath.getFileChannel(_os); } - FileChannel fileChannel = _randomAccessFile.getChannel(); - if (block) - _fileLock = fileChannel.lock(0, Long.MAX_VALUE, shared); + _fileLock = _fileChannel.lock(0, Long.MAX_VALUE, false); else - _fileLock = fileChannel.tryLock(0, Long.MAX_VALUE, shared); + _fileLock = _fileChannel.tryLock(0, Long.MAX_VALUE, false); return _fileLock != null; } catch (OverlappingFileLockException e) { @@ -242,6 +229,7 @@ else return true; } catch (IOException e) { + log.log(Level.FINE, e.toString(), e); return false; } } Index: modules/quercus/src/com/caucho/quercus/lib/file/FileInputOutput.java =================================================================== --- modules/quercus/src/com/caucho/quercus/lib/file/FileInputOutput.java (revision 3290) +++ modules/quercus/src/com/caucho/quercus/lib/file/FileInputOutput.java (working copy) @@ -65,7 +65,7 @@ private String _readEncodingName; private FileLock _fileLock; - private RandomAccessFile _randomAccessFile; + private FileChannel _fileChannel; private boolean _temporary; @@ -365,27 +365,25 @@ */ public void close() { - try { - _env.removeClose(this); - - _stream.close(); + _env.removeClose(this); - if (_temporary) - _path.remove(); - } catch (IOException e) { - log.log(Level.FINE, e.toString(), e); - } - + unlock(); + + _fileChannel = null; + try { - RandomAccessFile file = _randomAccessFile; - _randomAccessFile = null; - - if (file != null) { - file.close(); + RandomAccessStream ras = _stream; + _stream = null; + + if (ras != null) { + ras.close(); + + if (_temporary) + _path.remove(); } } catch (IOException e) { log.log(Level.FINE, e.toString(), e); - } + } } /** @@ -453,18 +451,14 @@ return false; try { - File file = ((FilePath) getPath()).getFile(); - - if (_randomAccessFile == null) { - _randomAccessFile = new RandomAccessFile(file, "rw"); + if (_fileChannel == null) { + _fileChannel = FilePath.getFileChannel(_stream); } - - FileChannel fileChannel = _randomAccessFile.getChannel(); if (block) - _fileLock = fileChannel.lock(0, Long.MAX_VALUE, shared); + _fileLock = _fileChannel.lock(0, Long.MAX_VALUE, shared); else - _fileLock = fileChannel.tryLock(0, Long.MAX_VALUE, shared); + _fileLock = _fileChannel.tryLock(0, Long.MAX_VALUE, shared); return _fileLock != null; } catch (IOException e) { @@ -486,6 +480,7 @@ return false; } catch (IOException e) { + log.log(Level.FINE, e.toString(), e); return false; } } Index: modules/quercus/src/com/caucho/quercus/lib/file/FileModule.java =================================================================== --- modules/quercus/src/com/caucho/quercus/lib/file/FileModule.java (revision 3290) +++ modules/quercus/src/com/caucho/quercus/lib/file/FileModule.java (working copy) @@ -1035,10 +1035,10 @@ } boolean shared = false; - boolean block = false; + boolean block = true; if (operation > LOCK_NB) { - block = true; + block = false; operation -= LOCK_NB; } Index: modules/util/src/com/caucho/vfs/VfsStream.java =================================================================== --- modules/util/src/com/caucho/vfs/VfsStream.java (revision 3290) +++ modules/util/src/com/caucho/vfs/VfsStream.java (working copy) @@ -84,6 +84,11 @@ position = 0; } + public OutputStream getOutputStream() + { + return _os; + } + public void setNewline(byte []newline) { this.newline = newline; Index: modules/util/src/com/caucho/vfs/FileReadStream.java =================================================================== --- modules/util/src/com/caucho/vfs/FileReadStream.java (revision 3290) +++ modules/util/src/com/caucho/vfs/FileReadStream.java (working copy) @@ -82,6 +82,15 @@ } /** + * Return the FileInputStream contained inside this + * FileReadStream object. + */ + public FileInputStream getFileInputStream() + { + return _is; + } + + /** * Returns true if there's an associated file. */ public boolean hasSkip() Index: modules/util/src/com/caucho/vfs/FilePath.java =================================================================== --- modules/util/src/com/caucho/vfs/FilePath.java (revision 3290) +++ modules/util/src/com/caucho/vfs/FilePath.java (working copy) @@ -39,6 +39,8 @@ import java.io.RandomAccessFile; import java.util.Map; +import java.nio.channels.FileChannel; + /** * FilePath implements the native filesystem. */ @@ -574,4 +576,38 @@ return false; } + + /** + * Get the FileChannel object contained inside a write stream + * opended via openWriteImpl or openAppendImpl. + */ + public static FileChannel getFileChannel(WriteStream ws) + { + VfsStream vfsStream = (VfsStream) ws.getSource(); + FileOutputStream fos = (FileOutputStream) vfsStream.getOutputStream(); + return fos.getChannel(); + } + + /** + * Get the FileChannel object contained inside a read stream + * opended via openReadImpl. + */ + public static FileChannel getFileChannel(ReadStream rs) + { + FileReadStream frs = (FileReadStream) rs.getSource(); + FileInputStream fis = frs.getFileInputStream(); + return fis.getChannel(); + } + + /** + * Get the FileChannel object contained inside a read/write + * random access stream opened via openRandomAccess. + */ + public static FileChannel getFileChannel(RandomAccessStream ras) + { + FileRandomAccessStream fras = (FileRandomAccessStream) ras; + RandomAccessFile raf = fras.getRandomAccessFile(); + return raf.getChannel(); + } + }