
Hi Cristophe,
Hello,
regarding thread local storage we have come up with a different perspective of the problem.
First we where not very happy with boost threads because it requires a copy of the functor object. This does not allow to put non copyable object as member variables of the functor object. Knowing that mutex are none
that's not a problem. You can always put a non-copyable object inside a struct and pass a smart_pointer to that struct.
We chose the start&run model used in many thread API because it allows to initialize the thread object before it is started and collect result after the thread terminated.
same can happen with current [thread] library.
The thread object is the obvious place to use as thread local storage. This is because stored data is explicitely defined and its use is statically checked. It is also automatically destroyed with the thread object is destroyed.
are you sure? what if the thread is ::Terminated?
Thread objects are dynamically allocated and referenced through intrusive pointer. Thus thread objects can have
same could be achieved with smart pointers.
In the thread local storage managed by the system/pthread we only store a pointer to the thread object. This is to allow to get access to the thread object from anywhere in the code. This is equivalent of the this variable for objects but for threads. Thus the thread class has a static self() method returning a reference on the current thread object.
the self() is a pretty good idea. However, the big issue is not when [thread] is used within a custom application, where you know exactly what TSS data you need. The issue is when you develop a library that depends on [thread] and needs TSS.
It also to be noted that boost thread implementation would start the thread before the boost thread object instantiation would complete. Such constrains should not be imposed to the users. There is thus a need to know
I'm not sure I follow. Could you please give an example?
Regarding synhcronization we have also made a slight move away from boost API which was aslo the best seen so far. We make a distinction between locks and latch. A lock has no method. When it is constructed it immediately attempts to lock the mutex, and the destructor release the mutex. Thus when a lock is instantiated, the mutex can be assumed to be locked by the thread who performed the instantiation on its call stack. When a latch is instantiated, the mutex is not locked. The following methods lock, unlock, try_lock and timed_lock are used to control the referenced mutex. When a latch variable is destroyed it automatically unlock the mutex if it was currently locking it.
I don't think this has bought you anything. In fact, I think it's more prone to error, since who's stopping you to do: void crazy() { some_lock l(mutex); l.lock(); }
We believe there was a possible confusion in the initial lock state of boost locks. It is not orthogonal.
Again, could you give an example? Best, John