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

Reply via email to