Boost.Thread problem with thread_specific_ptr<>::release ?
Dear Boosters! As I am still trying to figure out how to use the thread local storage pointer I found another strange behaviour. Perhaps I am misunderstanding the docs, or this might be a bug. System: VC6.0 CVS Head Problem: When using release on a tss variable, the associated automatic cleanup routine seems not to be updated correctly as it tries to delete the original pointer, instead of the 0-pointer. Example (simple modification of tss.cpp example): boost::thread_specific_ptr<int> value; void increment() { int* p = value.get(); ++*p; } void thread_proc() { value.reset(new int(0)); // initialize the thread's storage for (int i=0; i<10; ++i) { increment(); int* p = value.get(); assert(*p == i+1); } //******** added the following two lines int* p = value.release(); delete p; // deleting the released pointer //******* } int main(int argc, char* argv[]) { boost::thread_group threads; for (int i=0; i<5; ++i) threads.create_thread(&thread_proc); threads.join_all(); } In the debug version the program faults at exit, as the pointers are beeing freed a second time. I suspect the problem lies in the following function, as it does not set the cleanup handler if the value is 0 bool tss::set(void* value) { if (value && m_cleanup) { cleanup_handlers* handlers = get_handlers(); assert(handlers); if (!handlers) return false; cleanup_info info(m_cleanup, value); (*handlers)[m_key] = info; } return !!TlsSetValue(m_key, value); } Regards, Roland Schwarz
On Fri, 14 Nov 2003 19:30:58 +0100 (W. Europe Standard Time) Roland
Dear Boosters!
As I am still trying to figure out how to use the thread local storage pointer I found another strange behaviour. Perhaps I am misunderstanding the docs, or this might be a bug. System: VC6.0 CVS Head
Problem: When using release on a tss variable, the associated automatic cleanup routine seems not to be updated correctly as it tries to delete the original pointer, instead of the 0-pointer.
Example (simple modification of tss.cpp example):
boost::thread_specific_ptr<int> value;
void increment() { int* p = value.get(); ++*p; }
void thread_proc() { value.reset(new int(0)); // initialize the thread's storage for (int i=0; i<10; ++i) { increment(); int* p = value.get(); assert(*p == i+1); } //******** added the following two lines int* p = value.release(); delete p; // deleting the released pointer //******* }
int main(int argc, char* argv[]) { boost::thread_group threads; for (int i=0; i<5; ++i) threads.create_thread(&thread_proc); threads.join_all(); }
In the debug version the program faults at exit, as the pointers are beeing freed a second time. I suspect the problem lies in the following function, as it does not set the cleanup handler if the value is 0
bool tss::set(void* value) { if (value && m_cleanup) { cleanup_handlers* handlers = get_handlers(); assert(handlers); if (!handlers) return false; cleanup_info info(m_cleanup, value); (*handlers)[m_key] = info; } return !!TlsSetValue(m_key, value); }
Regards, Roland Schwarz
Dear Boosters, obviously I am doing something wrong. Either I am asking the wrong questions at this list, or the correct question but noone knows the answer, or noone cares about the issue in question. (I do not believe this last one.) Maybe my postings don't even get through to the list? Please can anyone give me a hint? Thank you, Roland Schwarz
Hello Roland,
obviously I am doing something wrong. Either I am asking the wrong questions at this list, or the correct question but noone knows the answer, or noone cares about the issue in question. (I do not believe this last one.)
I've been looking at your message, but unfortunately I cannot help you. For one, I don't use VC on Windows (pure Linux user ;-)) and I'm not that familiar with boost.threads. The code looks quite solid, but maybe it's a copy constructor somewhere that is making one copy too many, resulting in a double-free?
Maybe my postings don't even get through to the list?
They are coming through, and I thought I'd just let you know. Sorry I can't help you any more.... EJ
participants (2)
-
Erwin J.
-
Roland