Hi Brian,

On 7/26/19 12:42 AM, Brian Burkhalter wrote:

On Jul 11, 2019, at 12:52 AM, Peter Levart <peter.lev...@gmail.com <mailto:peter.lev...@gmail.com>> wrote:

On 7/11/19 9:47 AM, Peter Levart wrote:

http://cr.openjdk.java.net/~plevart/jdk-dev/8193072_File.undoDeleteOnExit/webrev.02/


Another thing to consider (done in above webrev.02) is what to do with unbalanced cancelDeleteOnExit(). I think it is better to throw exception than to silently ignore it. This way unintentional bugs can be uncovered which would otherwise just cause erratic behavior.

The above patch looks pretty good but unless I am not comprehending the code I think there may still be behavioral incompatibilities which might not be acceptable. For example, for the existing code base with the following sequence of operations

File file1, file2, file3;

file1.deleteOnExit();
file2.deleteOnExit();
file3.deleteOnExit();

the deletion order is file3, file2, file1.

...and the same order remains with the proposed patch for above sequence of operations.


For the proposed patch with the following sequence of operations

file1.deleteOnExit();
file2.deleteOnExit();
file3.deleteOnExit();
file1.cancelDeleteOnExit(); // file1 is removed from the map
file2.cancelDeleteOnExit(); // file2 is removed from the map
file2.createNewFIle();
file2.deleteOnExit(); // file2 is added back into the map
file1.createNewFIle();
file1.deleteOnExit(); // file1 is added back into the map

the deletion order is (I think) file1, file2, file3 which is the reverse of the order of initial registration.

Right, and above sequence of operations is something that is not present in current codebases as there is no cancelDeleteOnExit() method yet. So more to the point would be a comparison of behaviors with some code sequence that doesn't include the not yet present method. Suppose the following:

file1.deleteOnExit();
file1.createNewFile();
file2.deleteOnExit();
file2.createNewFile();
file3.deleteOnExit();
file3.createNewFile();

file1.delete();
file2.delete();

file2.deleteOnExit();
file2.createNewFile();
file1.deleteOnExit();
file1.createNewFile();

Yes, with above sequence the order of deletion using current codebase will be file3, file2, file1, while with the patch, it would be file1, file2, file3.


Of course it is conceivable to change the specification but that seems dangerous somehow.

Of course there could be a situation where the change of order mattered for the correct logic of the program - imagine an empty "signal" file which guarantees with its presence that another "payload" file is present and fully written/consistent. You would want to maintain such an invariant so you would 1st register the payloadFile.deleteOnExit() following with signalFile.deleteOnExit(). But most such schemes are one-way only. If you wanted to somehow delete the signal file and then re-create it later after updating the payload file, you might already be doing the re-registration in the correct order (if you are just repeating the same code sequence as in initial registration), but you are making a concurrency mistake anyway as you are faced with a race inherent to an ABA problem that has nothing to do with registration to delete files on exit.

So I argue that any working scheme that features multiple registrations of the same file must be because of dependencies among them stemming from the filesystem hierarchy. For example, you would 1st want to register a new File("/path/to/dir").deleteOnExit() followed by new File("/path/to/dir/file.ext").deleteOnExit() so that on exit, the file is deleted 1st and then the dir which must be empty for deletion to succeed.

In this hypothetical example, you might, at some point delete the file and unregister it (keeping the dir present and registered) and later re-register and re-create the file. The deletion will still work correctly in this case. Or you might want to delete the file and dir and unregister them for them to be re-registered and re-created later. If such code is present now (modulo de-registering) it probably performs the re-registration in the correct order already.

In other words, any code that changes the deletion order with the patch but doesn't with current codebase is re-registering the same file (in wrong order) relying on the fact that the file is already registered (in the correct order). Only such code could break, but the chances are great the it won't.


Also for the patch above for this sequence of operations

file1.deleteOnExit();
file2.deleteOnExit();
file3.deleteOnExit();
file1.cancelDeleteOnExit(); // file1 is removed from the map
file2.cancelDeleteOnExit(); // file2 is removed from the map
file2.createNewFIle();
file1.createNewFIle();

then file3 is deleted on exit but file1 and file2 are not which differs from current behavior.


Right, because there is "no current behavior" with above sequence of operations, because there is currently no cancelDeleteOnExit() method. So there's no valid comparison.



As Roger wrote

On Jul 9, 2019, at 7:34 AM, Roger Riggs <roger.ri...@oracle.com <mailto:roger.ri...@oracle.com>> wrote:

The filename is the key and there is no way to determine if it is the original file or a replacement. deleteOnExit Wins!

the filename is the key and if we toss the key then we lose the order of registration. Given this I am not sure any more that it is possible to fix this issue without introducing an incompatible behavioral change.


What above a system property that restores the previous behavior and is deprecated at start with removal to be determined?


Regards, Peter



Thanks,

Brian


Reply via email to