Home > Software design >  WinAPI: Thread local storage cleanup
WinAPI: Thread local storage cleanup

Time:12-14

In WinAPI you can create and access thread local storage using functions such as TlsAlloc, TlsGetValue, TlsSetValue and TlsFree. The API supposes that you will store pointers in the thread local storage (for sure you can store size_t integers casted to pointers, but often we would like to store more information). So, probably this memory will be allocated by every thread which uses this data. But the problem is how to free this memory at thread exit.

In pthreads you have an optional destructor argument for pthread_key_create function (pthreads version of TlsAlloc). But in raw WinAPI TlsAlloc doesn't provide such option. How to implement a custom destructor for thread local storage using only WinAPI and plain C (so no modern C thread local storage which supports object destructors on the compiler level)?

I'm writing a normal program, not a DLL, so I don't care about the corner case "DLL unloaded before program exit, so the destructor code became unavailable". I think, I am looking for a function similiar to atexit, but on thread level.

CodePudding user response:

On Windows Vista , if you switch to fiber-local storage (FLS) instead of thread-local storage (TLS), you can then use FlsAlloc() to register a callback function that can be called at thread exit.

PFLS_CALLBACK_FUNCTION callback function

An application-defined function. If the FLS slot is in use, FlsCallback is called on fiber deletion, thread exit, and when an FLS index is freed. Specify this function when calling the FlsAlloc function. The PFLS_CALLBACK_FUNCTION type defines a pointer to this callback function. FlsCallback is a placeholder for the application-defined function name.

See Raymond Chen's article: Fibers aren’t useful for much any more; there’s just one corner of it that remains useful for a reason unrelated to fibers

But there’s still one part of Windows fibers that is still useful: The fiber destruction callback.

...

The callback function is called when a fiber is destroyed. This is the fiber equivalent of DLL_THREAD_DETACH, except that it’s not just for DLLs. Executables can use it too.

Even better: When you deallocate the fiber-local storage slot, the callback is invoked for every extant fiber. This lets you clean up all your per-fiber data before it’s too late.

...

Even though fibers are basically dead, you can use fiber-local storage to get an improved version of thread-local storage.

If you don't create multiple fibers per thread, FLS will act the same as TLS, but you will get the added benefit of the destruction callback.

  • Related