[thread] thread_specific_ptr is not initialized with NULL

Hi,
As I understand from documentation, once thread_specific_ptr is created,
first call to get() should return NULL in all threads. Actually sometimes it
doesn't happen. Consider the following scenario:
1) thread T1 initializes some global tss object (by doing "new" on global
thread_specific_ptr<>*)
2) thread T2 tries to read the value with get(), and gets null. It sets a
correct value (unsigned int 42)
3) thread T1 deletes tss object, and allocates a new one instead.
4) thread T2 tries to read the value from the new object
So I expected that in (4) thread T2 will get NULL again. Actually, when new
object created in (3) is created in same memory location, T2 gets the
original value in (4), and not NULL. When new pointer allocated in (3) is
different, T2 gets NULL as expected (verified using "placement new" to
control location of the tss object).
Is it a bug or inpropriate use pattern?
The code that demonstrates the issue is listed below (please ignore
synchronization issues) - note the line with a comment: when I do "new
(buf2) ..." instead, it works as expected.
Thanks,
Michael
======================================
#include

"Michael Gopshtein"
Hi,
As I understand from documentation, once thread_specific_ptr is created, first call to get() should return NULL in all threads. Actually sometimes it doesn't happen. Consider the following scenario:
1) thread T1 initializes some global tss object (by doing "new" on global thread_specific_ptr<>*) 2) thread T2 tries to read the value with get(), and gets null. It sets a correct value (unsigned int 42) 3) thread T1 deletes tss object, and allocates a new one instead.
This is now undefined behaviour. If you destroy a thread_specific_ptr whilst any thread has a non-NULL value then you cannot rely on what happens subsequently with respect to any thread that tries to use that or a new thread_specific_ptr instance.
4) thread T2 tries to read the value from the new object
So I expected that in (4) thread T2 will get NULL again. Actually, when new object created in (3) is created in same memory location, T2 gets the original value in (4), and not NULL. When new pointer allocated in (3) is different, T2 gets NULL as expected (verified using "placement new" to control location of the tss object).
Is it a bug or inpropriate use pattern?
Inappropriate use pattern. 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

Thanks.
That's not the case with "native" TLS support (it promises to zero out all
values in released slot), but it's good to know that this is undefined for
thread_specific_ptr.
BTW, is it because such pattern of use is not considered interesting? For
example, in our application there are "Database" objects which are created
and destroyed dynamically, and each Database has a unique connection per
thread, which are stored in the TLS. The connections are also stored in
seperate lists, and are released when the Database is no longer in use - so
the "default" behavior of the native API (both Win32 and pthreads) is OK
with us.
Anyway, thanks again for the info.
Michael
"Anthony Williams"
"Michael Gopshtein"
writes: This is now undefined behaviour. If you destroy a thread_specific_ptr whilst any thread has a non-NULL value then you cannot rely on what happens subsequently with respect to any thread that tries to use that or a new thread_specific_ptr instance.
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

"Michael Gopshtein"
That's not the case with "native" TLS support (it promises to zero out all values in released slot), but it's good to know that this is undefined for thread_specific_ptr.
BTW, is it because such pattern of use is not considered interesting? For example, in our application there are "Database" objects which are created and destroyed dynamically, and each Database has a unique connection per thread, which are stored in the TLS. The connections are also stored in seperate lists, and are released when the Database is no longer in use - so the "default" behavior of the native API (both Win32 and pthreads) is OK with us.
Allowing this is a potential for memory leaks. pthread_key_delete does not run the destructor function, so if you have dynamically allocated memory (or other resource) referenced by the key value you have a leak. By its very nature, thread_specific_ptr has dynamically allocated memory for each key value, so it is important to ensure that it is correctly deleted in each thread. 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
participants (2)
-
Anthony Williams
-
Michael Gopshtein