views:

50

answers:

2

I need to make use of thread-local storage in a cross-platform project. Under *IX I am using pthreads and can avoid memory leaks thanks to the nice destructor function pointer passed as the second argument to pthread_key_create, but in Windows TlsAlloc has no such thing. Nor can I find a general place where any function is called on thread exit (otherwise I would homebrew some list of function pointers that get called at exit).

As it stands it seems that I have basically a situation where in order to actually use thread local storage I need to allocate my own space on the heap and pass a pointer to TlsSetValue, but if the thread exits ... I have no way of ensuring the memory was freed (other than someone explicitly calling TlsGetValue and delete/free/HeapFree/etc at the end of the thread function.

Does anyone know of a better way?

+2  A: 

The entry point of a DLL (DLLmain) is called on thread exit with a reason code of DLL_THREAD_DETACH. It is fairly straightforward to write a DLL that keeps track of functions to call on thread exit.

Alternatively, use Boost.Thread and the boost::this_thread::at_thread_exit function to register a function to be called on thread exit, or use boost::thread_specific_ptr to wrap the TLS usage entirely.

Anthony Williams
A: 

You can get yourself a nice "finalizer" to get rid of thread-specific resources, even if the thread is terminated: use RegisterWaitForSingleObject to wait on a copy (via DuplicateHandle) of the threads' handle - you have to use the cloned handle, cause registered waits can't handle handle {no pun intended} closing.
Use a heap allocated structure/record to hold the finalized resources, the handle waited for and the wait handle itself, cause the finalizer will run in the system threadpool, NOT the finalized thread (which will be already dead by the time). And don't forget to finalize the finalizer :)

Viktor Svub