
----- Original Message ----- From: "Anthony Williams" <anthony.ajw@gmail.com> To: <boost@lists.boost.org> Sent: Monday, September 22, 2008 6:05 PM Subject: Re: [boost] [thread] TSS cleanup
For example:
for(int i = very_big_number;i--;i > 0) boost::thread_specific_ptr<int> p(new int);
To my knowledge, the pointer returned by new in this case is freed. But does the int* that is created to store the pointer to new int is also freed, or this program will get only bigger and bigger?
As written this code is fine: it will reuse the same slot since p will have the same address each time through, and it uses the address as the key. It is undefined behaviour if other threads can still try and access a given thread_specific_ptr (including having data stored associated with it) after it has been destroyed.
Hi, I didn't know that the key was the address of the variable. As pthread_getspecific ensures constant complexity, I expected the same for boost::thread_specific_ptr, but if the key is the address this seams not possible. So which is the complexity of boost::thread_specific_ptr<T>::get()? Looking at the code we see that is O(N). IMHO, the constant complexity is one the major requirements of such a feature. I supose you had some good raison to not use an index key instead of the address. In addition, the release and reset functions inccur on two lookups on the set of thread specific pointers. T* release() { T* const temp=get(); detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false); return temp; } void reset(T* new_value=0) { T* const current_value=get(); if(current_value!=new_value) { detail::set_tss_data(this,cleanup,new_value,true); } } If the set_tss_data returns the old value these two functions could be encoded with reduced complexity like that. T* release() { return detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false); } void reset(T* new_value=0) { detail::set_tss_data(this,cleanup,new_value,true); } Does the thread_local C++0x feature requires constant complexity on getting and setting the value? It is a pitie that we can not use the thread_local (or the equivalent) when the compiler provies to define boost::thread_specific_ptr. Or maybe the preprocesor can help? #define BOOST_THREAD_LOCAL(T,name,init_value) \ class BOOST_THREAD_LOCAL##name { private: thread_local static T value init_value; public: T* get() const { return &value; } } name; In the mean time, it would be great if you add the nature of the key, the complexity and the rationale on this design decision on the documentation. Thanks, Vicente