8193072: File.delete() should remove its path from DeleteOnExitHook.files
Peter Levart
peter.levart at gmail.com
Thu Jul 11 07:47:11 UTC 2019
Hi,
On 7/11/19 3:51 AM, Ivan Gerasimov wrote:
>
> On 7/10/19 5:17 PM, Brian Burkhalter wrote:
>> I incorporated Peter’s version, adding the security check in
>> cancelDeleteOnExit(), tweaking its verbiage along with that of
>> deleteOnExit(), and modified the test DeleteOnExit to verify the new
>> method. The updated version is here:
>>
>> http://cr.openjdk.java.net/~bpb/8193072/webrev.03/
>> <http://cr.openjdk.java.net/~bpb/8193072/webrev.03/>
> There is possibility of a race here in a scenario like this:
>
> File dir = new File("dir");
> File file = new File("dir/file");
>
> -- thread 1 --
> dir.deleteOnExit();
> file.deleteOnExit();
> ///
> dir.cancelDeleteOnExit();
> //// thread 2 intervenes
> file.cancelDeleteOnExit();
> -- end --
>
> -- thread 2 --
> dir.deleteOnExit();
> file.deleteOnExit();
> -- end --
>
> The result will be that the order of the registered files will change,
> and JVM will try to delete dir first (this will fail as it is not empty).
>
> Of course it could be avoided, if cancellation were done in reverse
> order, though it's not immediately obvious from the documentation.
Hm,
LinkedHashMap.computeIfAbsent/computeIfPresent can also honor the so
called "access order" which always moves the entry to the end of the
linked list regardless of whether the entry is already present or not.
So in above scenario and if LinkedHashMap was constructed with
accessOrder=true, the registration order of paths after each operation
would be as follows (the order of deletion is the reverse order of the
presented registration order):
File dir = new File("dir");
File file = new File("dir/file");
-- thread 1 --
dir.deleteOnExit();
[dir]
file.deleteOnExit();
[dir, dir/file]
dir.cancelDeleteOnExit();
[dir/file]
-- thread 2 --
dir.deleteOnExit();
[dir/file, dir]
file.deleteOnExit();
[dir, dir/file]
-- thread 1 --
file.cancelDeleteOnExit();
[dir, dir/file]
But that is just coincidence. There are other interleavings which would
cause LHM "access order" to reorder paths in undesired way. Perhaps the
best behavior would be for deleteOnExit() to reorder the file to the end
of the registration list while cancelDeleteOnExit() to not change the
order of registered paths. For example, like this:
http://cr.openjdk.java.net/~plevart/jdk-dev/8193072_File.undoDeleteOnExit/webrev.02/
This does however change the order of registration for sequences like
the following:
file1.deleteOnExit();
file2.deleteOnExit();
file1.deleteOnExit();
Order of deletion now: file2, file1
Order of deletion with this patch: file1, file2
But considering that programs that register multiple files do so
consistently (always the same set of related files in one go in the same
order) or register unrelated files in unimportant order, such behavior
is perhaps acceptable.
What do you think?
Regards, Peter
More information about the core-libs-dev
mailing list