Skip to content

Commit 1724dc5

Browse files
committed
Directly use the FileChannel from ChannelLock for WRITE LockedFileChannel
This fixes behaviour on Windows, where the we cannot open another FileChannel on the write-locked path. We have to use the channel that we locked.
1 parent 86712a9 commit 1724dc5

2 files changed

Lines changed: 12 additions & 32 deletions

File tree

src/main/java/org/janelia/saalfeldlab/n5/ChannelLock.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,19 @@ private ChannelLock(final FileChannel channel, final FileLock lock) {
2525
}
2626

2727
public void close() throws IOException {
28-
lock.release();
28+
29+
// NB: We do not call lock.release() here, because it may throw an
30+
// exception if the channel is already closed. Instead, we just close
31+
// the channel. This will automatically release the lock. (And it is ok
32+
// to close an already closed channel.)
33+
2934
channel.close();
3035
}
3136

37+
FileChannel getChannel() {
38+
return channel;
39+
}
40+
3241
/**
3342
* Create a {@link FileChannel} on the given {@code path} and lock it with a
3443
* system-level {@link FileLock}. If there is an existing overlapping file

src/main/java/org/janelia/saalfeldlab/n5/KeyLockState.java

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -177,23 +177,8 @@ LockedFileChannel acquireWrite() throws IOException {
177177
}
178178

179179
// We have a WRITE ChannelLock.
180-
// Try to open a FileChannel.
181-
final FileChannel channel;
182-
try {
183-
channel = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
184-
} catch (IOException e) {
185-
// Something went wrong. Back off.
186-
try {
187-
channelLock.close();
188-
} finally {
189-
channelLockMutex.release();
190-
}
191-
throw e;
192-
}
193-
194-
// We have a FileChannel.
195180
// Create a LockedFileChannel that will releaseWrite() when it is closed.
196-
return new LockedFileChannel(channel, this::releaseWrite);
181+
return new LockedFileChannel(channelLock.getChannel(), this::releaseWrite);
197182
} catch (InterruptedException e) {
198183
throw new IOException(e);
199184
}
@@ -214,22 +199,8 @@ LockedFileChannel tryAcquireWrite() {
214199
}
215200

216201
// We have a WRITE ChannelLock.
217-
// Try to open a FileChannel.
218-
final FileChannel channel;
219-
try {
220-
channel = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
221-
} catch (IOException e) {
222-
// Something went wrong. Back off.
223-
try {
224-
releaseChannelLock();
225-
} catch (IOException ignored) {
226-
}
227-
return null;
228-
}
229-
230-
// We have a FileChannel.
231202
// Create a LockedFileChannel that will releaseWrite() when it is closed.
232-
return new LockedFileChannel(channel, this::releaseWrite);
203+
return new LockedFileChannel(channelLock.getChannel(), this::releaseWrite);
233204
}
234205

235206
void releaseWrite() throws IOException {

0 commit comments

Comments
 (0)