[cpp-threads] N2880 and thread_local variables

Anthony Williams anthony at justsoftwaresolutions.co.uk
Mon Jun 8 23:15:24 BST 2009


Hi,

I have been thinking about the issue of thread_local variables with 
destructors and lifetime that is discussed in N2880, and would like to 
suggest a possible solution.

My suggestion is this: create a new class thread_local_context which is 
intended to be used in an RAII manner. Creating an instance creates a 
new context on the calling thread for thread_local variables to be 
associated with. When the object is destroyed it destroys all 
thread_local variables modified on this thread since it was created.

Destroying such an object from a thread other than that in which it was 
created would be an error, as would destroying such objects in any order 
other than the reverse of their construction within a single thread.

Nesting such objects would create a new (blank) context for thread_local 
variables, and the outer context would be restored when the nested 
object was destroyed. Alternatively, nested contexts could inherit the 
set of thread_local variables from their parent context, and just 
destroy any newly-set values when the nested context is destroyed.

This could then be used to ensure that thread-local variables are 
cleaned up before waiting threads are notified when using mechanisms 
other than thread::join to communicate task completion. e.g. 
std::packaged_task::operator() could be written so as to execute the 
contained task within the scope of a thread_local_context, but only set 
the "ready" flag on the future outside the scope, thus ensuring that the 
thread locals are destroyed before any waiting threads see the future as 
set. Hypothetically:

std::packaged_task<FunctionSig>::operator()(Args... args)
{
     {
         thread_local_context context;
         try
         {
             associated_state.set_value(stored_func(args...));
         }
         catch(...)
         {
             associated_state.set_exception(std::current_exception());
         }
     }
     associated_state.mark_ready();
}

If we made this facility available directly to users then they could use 
it wherever they were using facilities other than thread::join to signal 
thread completion. It could also be used inside any std::async function 
to avoid the lifetime issues raised in N2880.

Obviously, this class would need to be intimately tied into the 
compiler's thread_local implementation.

Comments?

Anthony
-- 
Author of C++ Concurrency in Action | http://www.manning.com/williams
just::thread C++0x thread library   | http://www.stdthread.co.uk
Just Software Solutions Ltd         | http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976



More information about the cpp-threads mailing list