For purposes of thread local cleanup I need to create an assertion that checks if the current thread was created via boost::thread. How can I can check if this was the case? That is, how can I check if the current thread is handled by boost::thread?
I simply need this to do a cleanup of thread local storage when the thread exits. Boost's thread_local_ptr appears to only work if the thread itself is a boost thread.
Note that I'm not doing the check at cleanup time, but sometime during the life of the thread. Some function calls one of our API/callbacks (indirectly) causing me to allocate thread-local storage. Only boost threads are allowed to do this, so I need to detect at that moment if the thread is not a boost thread.
Refer to Destruction of static class members in Thread local storage for the problem of not having a generic cleanup handler. I answered that and realized pthread_clenaup_push won't actually work: it isn't called on a clean exit form the thread.
While I don't have answer to detect a boost thread the chosen answer does solve the root of my problem. Boost thread_specific_ptr's will call their cleanup in any pthread. It must have been something else causing it not to work for me, as an isolated test shows that it does work.
The premise for your question is mistaken :) boost::thread_specific_ptr works even if the thread is not a boost thread. Think about it -- how would thread specific storage for the main thread work, seeing as it's impossible for it to be created by boost? I have used boost::thread_specific_ptr from the main thread fine, and although I haven't examined boost::thread_specific_ptr's implementation, the most obvious way of implementing it would work even for non-boost threads. Most operating systems let you get a unique ID number for the current thread, which you can then use as an index into a map/array/hashtable.
More likely you have a different bug that prevents the behavior you're expecting to see from happening. You should open a separate question with a small compilable code sample illustrating the unexpected behavior.
You can't do this with a static assertion: That would mean you could detect it at compile time, and that's impossible.
Assuming you mean a runtime check though:
If you don't mix boost::thread
with other methods, then the problem just goes away. Any libraries that are creating threads should already be dealing with their own threads automatically (or per a shutdown function the API documents that you must call).
Otherwise you can keep, for example, a container of all pthread_t
s you create not using boost::thread
and check if the thread is in the container when shutting down. If it's not in the container then it was created using boost::thread
.
EDIT: Instead of trying to detect if it was created with boost::thread
, have you considered setting up your application so that the API callback can only occur in threads created with boost::thread
? This way you prevent the problem up front and eliminate the need for a check that, if it even exists, would be painful to implement.
Each time a boost thread ends, all the Thread Specific Data gets cleaned. TSD is a pointer, calling delete p*
at destruction/reset.
Optionally, instead of delete p*
, a cleanup handler can get called for each item. That handler is specified on the TLS constructor, and you can use the cleanup function to do the one time cleaning.
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp>
void cleanup(int* _ignored) {
std::cout << "TLS cleanup" << std::endl;
}
void thread_func() {
boost::thread_specific_ptr<int> x(cleanup);
x.reset((int*)1); // Force cleanup to be called on this thread
std::cout << "Thread begin" << std::endl;
}
int main(int argc, char** argv) {
boost::thread::thread t(thread_func);
t.join();
return 0;
}