8193072: File.delete() should remove its path from DeleteOnExitHook.files

Peter Levart peter.levart at gmail.com
Wed Jul 10 12:36:07 UTC 2019


On 7/9/19 8:08 PM, Brian Burkhalter wrote:
>> On Jul 9, 2019, at 8:31 AM, Brian Burkhalter <brian.burkhalter at oracle.com> wrote:
>>> Since deleteOnExit() is an deliberate act, perhaps there should be a corresponding withdrawDeleteOnExit() that reverses it so that it is intentional and not a side-effect of other File methods.
>> I think this is a better idea. Perhaps “cancelDeleteOnExit()”.
> If we want to go this route, here is one possibility:
> http://cr.openjdk.java.net/~bpb/8193072/webrev.02/

With only one method (deleteOnExit) there are no races because the 
method is idempotent if called with the same File multiple times from 
different threads. Adding cancelDeleteOnExit() makes things problematic 
in concurrent setting. Imagine the following code:

         File f = new File("/path/to/file");

         // 1st register hook...
         // ...then attempt file creation so there's no chance
         // the file is left behind if VM unexpectedly exits
         if (f.createNewFile()) {
             ... process something using f
             // 1st delete file...
         // ...then unregister hook so there's no chance
         // the file is left behind if VM unexpectedly exits
         // unregister hook also after we registered it but
         // then file creation failed.

This code is correct if executed in a single thread. But imagine two or 
more threads competing to create the same file and properly delete it 
afterwards with registering and un-registering the hook to cover cleanup 
when VM exits during processing...

There are various interleavings of threads that could cause the file to 
be left undeleted when VM exits.

To cover concurrent scenarios such as above, the code could use 
reference counting. Like in the following patch:


Regards, Peter

More information about the core-libs-dev mailing list