Details
-
Enhancement
-
Resolution: Fixed
-
P4
-
20
-
b06
Description
In Shutdown.exit there used to be a window between running the shutdown hooks and calling halt where another thread could slip in its own call to exit. This was to allow finalizers to call exit and halt immediately. But runFinalizersOnExit was removed (JDK-8198249), so that's no longer an issue.
But that change left a small window ajar for another thread to slip in a call to exit that will immediately call halt. Specifically, in Shutdown.exit there is an initial synchronized block that tests `status != 0 && VM.isShutdown()` and calls halt immediately if so. This creates a very small window of opportunity, where a previous call to exit has completed runHooks (and so made VM.isShutdown true) and calling halt. A different thread calling exit in that window will override the original status.
I think there is no need for that, and that whole synchronized block should be deleted. Having it makes the code harder to understand, to no purpose.
Consider a call to exit.
If some other thread has already called exit, it owns the Shutdown.class lock and will retain it through its call to halt. The new call to exit will just block on the Shutdown.class lock, regardless of whether the earlier call has completed running the shutdown hooks or not.
If instead, some other thread has already called shutdown (which doesn't call halt), then the new call to exit will again block on the Shutdown.class lock. But this time it will obtain the lock when the call to shutdown completes. It will then attempt to run the shutdown hooks and discover they've already been run, so do nothing with them. It will then proceed on to call halt.
But that change left a small window ajar for another thread to slip in a call to exit that will immediately call halt. Specifically, in Shutdown.exit there is an initial synchronized block that tests `status != 0 && VM.isShutdown()` and calls halt immediately if so. This creates a very small window of opportunity, where a previous call to exit has completed runHooks (and so made VM.isShutdown true) and calling halt. A different thread calling exit in that window will override the original status.
I think there is no need for that, and that whole synchronized block should be deleted. Having it makes the code harder to understand, to no purpose.
Consider a call to exit.
If some other thread has already called exit, it owns the Shutdown.class lock and will retain it through its call to halt. The new call to exit will just block on the Shutdown.class lock, regardless of whether the earlier call has completed running the shutdown hooks or not.
If instead, some other thread has already called shutdown (which doesn't call halt), then the new call to exit will again block on the Shutdown.class lock. But this time it will obtain the lock when the call to shutdown completes. It will then attempt to run the shutdown hooks and discover they've already been run, so do nothing with them. It will then proceed on to call halt.
Attachments
Issue Links
- csr for
-
JDK-8289824 Simplification in java.lang.Runtime::exit
-
- Closed
-
- relates to
-
JDK-8198249 Remove deprecated Runtime::runFinalizersOnExit and System::runFinalizersOnExit
-
- Resolved
-
-
JDK-8290036 Define and specify Runtime shutdown sequence
-
- Resolved
-