Windows TLS - Only register the atexit hook when cleanup can be unloaded#157645
Conversation
|
|
|
I like avoiding @bors try jobs=msvc,mingw |
This comment has been minimized.
This comment has been minimized.
…maybe-deadlock-on-shutdown, r=<try> Windows TLS - when `cleanup` can be unloaded, leak instead of running dtors in `atexit` try-job: *msvc* try-job: *mingw*
|
Hm, looking at the current docs for LocalKey, it says:
This suggests to me we should favour attempting to run dtors but document the caveats. A deadlock is not a memory safety issue and many types of dtors (e.g. freeing memory) likely won't deadlock. Unloading a DLL (outside of program termination) is a niche use case but not so niche that I think we can justify not running dtors at all if the API claims to bias towards running them. |
Actually, seems like I was wrong about the cause of the deadlock: the issue is specifically calling I'll need to investigate this a bit more and I'll update the impl once I have a better idea if the fix is legit. |
282e4fe to
6bf8d21
Compare
cleanup can be unloaded, leak instead of running dtors in atexitcleanup can be unloaded, do not register the atexit hook
6bf8d21 to
6830dac
Compare
cleanup can be unloaded, do not register the atexit hookatexit hook when cleanup can be unloaded
6830dac to
b545eb8
Compare
Followup to #148799 - One of the motivations was to remove the "Synchronization in thread-local destructors" limitation (see the docs). However, it is still possible to deadlock on Windows with a destructor that uses a
join, but only during an application shutdown.(Edited. The original PR leaked the dtors when a DLL was unloaded.)
This is because calling
FlsFreefrom theatexithook from the main executable can deadlock if other threads are also running FLS destructors.This PR tweaks the implementation to only register the hook if
cleanupcan be unloaded, meaning we are loaded as a DLL.This has an added benefit of not triggering
FlsFreeat all during normal application shutdown, which is the most common case and is now handled more naturally by the Windows runtime (which calls the FLS hooks without holding the load-lock).Checking if the
cleanuphook is unload-able is done by checking if it is in the same module as the main exeGetModuleHandleExW(FLAG_FROM_ADDRESS, cleanup) == GetModuleHandleW(ptr::null()).Join-on-Drop on Process Exit Deadlock Example
r? @ChrisDenton