gnustep / libs-base

The GNUstep Base Library is a library of general-purpose, non-graphical Objective C objects.
https://www.gnustep.org/
GNU General Public License v2.0
936 stars 282 forks source link

libdispatch threads should call GSUnregisterCurrentThread() on exit #428

Open triplef opened 3 months ago

triplef commented 3 months ago

Threads started by libdispatch currently don’t clean up their NSThread data when the threads exit. This can cause issues e.g. when [[NSThread currentThread] threadDictionary] is used from such threads as this data will never get released.

libdispatch has a _dispatch_install_thread_detach_callback() hook (currently only available on Android) that can be used for this. We currently use a libdispatch patch to make the hook available on all platforms and install a hook to call GSUnregisterCurrentThread() on thread exit in our app.

It would be nice to install the hook callback from libs-base if the hook is available. To start with I’ll open a libdispatch pull request with our patch.

triplef commented 2 months ago

Opened https://github.com/apple/swift-corelibs-libdispatch/pull/841.

rfm commented 2 months ago

This sounds like some sort of bug ... as far as I can see cleanup should take place irrespective of how a thread was started, libdispatch is in no way a special case and I don't see why it should need an extra callback. The way it is supposed to work is that GS_THREAD_KEY_INIT registers a a function (via pthread_key_create() or FlsAlloc() on windows) to be called when a thread exits, and that function performs the cleanup. This should work irrespective of what code creates the thread.

rfm commented 14 hours ago

Threads started by libdispatch currently don’t clean up their NSThread data when the threads exit. Are you sure this is the case? If so, do you know what is preventing the cleanup from happening? Is there some path in which GS_THREAD_KEY_INIT is not called? Or is libdispatch somehow overriding it?