NOT_INTERRUPTIBLE OpenOption and how that should fit with InterruptibleChanne

Alan Bateman alan.bateman at oracle.com
Sun Jan 5 09:53:08 UTC 2025


On 26/12/2024 10:15, Bruno Ploumhans wrote:
> Hi,
>
> I opened a PR that adds StandardOpenOptions.NOT_INTERRUPTIBLE to
> expose and supersede FileChannelImpl#setUninterruptible. However, this
> needs more discussion because FileChannel implements
> InterruptibleChannel.
>
> Here are some thoughts to kick-start the discussion:
> - The documentation of InterruptibleChannel does not currently account
> for implementations that might not be interruptible. Same for the
> documentation of Thread.interrupt(). That needs changing.
> - Alan suggested in previous discussion (2018) a new `boolean
> isInterruptible()` method.
> - I wonder if the ability to pass a `boolean uninterruptible` flag
> should be exposed in AbstractUninterruptibleChannel, or if that should
> be kept an implementation detail of FileChannelImpl.
>
> In any case, I am happy to experiment with various solutions.
>
This is a topic that I've looked several times including explorations 
and prototypes of four options:

1. Changing FileChannel to not extend AbstractInterruptibleChannel
2. An OpenOption to opt out of interrupt closing the channel
3. An OpenOption to opt in to interrupt closing the channel
4. Specifying that interrupt does not close the channel but specified to 
allow for compatibility with long standing behavior

There are pros and cons to all.

For the options explored then most of the change is specification with 
the starting point for all was to re-specify async close of FileChannel 
to align with long standing behavior. If you look at how async close of 
a FileChannel works on Windows or with virtual threads then you'll see 
what I mean. There is also the issue that the lock methods specify that 
FileLockInterruptionException is thrown without closing the channel but 
the implementation differs.

My view on this has changed from when I first looked at it a few years 
ago. Right now, I think #4 may be the best option. The spec changes that 
I have from that option are:

- Changes to FileChannel to specify that it deviates from 
InterruptibleChannel to allow for close to wait for all outstanding I/O 
operations to end. This allows for long standing behavior. As part of 
this, FileChannel overrides the specification of implCloseChannel.

- Changes to FileChannel to specify that it deviates from 
InterruptibleChannel so that interrupt does not close the channel but 
allows for an implementation specific means for interrupt to close the 
channel.

- Changes to the specification of Thread.interrupt, 
ClosedByInterruptException, all methods in FileChannel that throw 
ClosedByInterruptException, FileLockInterruptionException and the 
FileChannel lock methods.

The main thing with this option is identifying any common usages where 
ClosedByInterruptException may be depended on, e.g. trying to shutdown 
something when threads are blocked indefinitely in file I/O operations. 
Such usages are likely file access over a network or maybe transfer 
to/from a channel backed by a network connection. Any help to identify 
such usages would be helpful to assess the compatibility impact of the 
options that change default behavior.

Your exploration is #2. The spec changes that I did when prototyping 
this option including changes to all the above spec areas, and also 
everywhere that opens a file, e.g. AsynchronousFileChannel. It is 
clearly the least risky from a compatibility perspective as it doesn't 
change default behavior but also the least satisfactory option too.

-Alan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/nio-dev/attachments/20250105/3869d3c3/attachment-0001.htm>


More information about the nio-dev mailing list