Boost logo

Boost :

Subject: Re: [boost] [thread] TSS cleanup
From: Felipe Magno de Almeida (felipe.m.almeida_at_[hidden])
Date: 2008-09-22 17:14:46


On Mon, Sep 22, 2008 at 1:05 PM, Anthony Williams <anthony.ajw_at_[hidden]> wrote:
> "Felipe Magno de Almeida" <felipe.m.almeida_at_[hidden]> writes:
>
>> I would like to know if the storage created for
>> boost::thread_specific_ptr in the tss
>> specific code for win32 is free'd after the destruction of said
>> boost::thread_specific_ptr, or
>> if it stays until the end of the process.
>
> Storage is allocated on a per-thread basis, and freed when the thread exits.
>
>> 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.

Well, so for spirit it would indeed get only bigger. Since it will hardly
reuse slots.
I see the tss algorithm is linear as well.

> If you create and destroy thread_specific_ptr instances all over the
> place then in general this will increase the list for each thread that
> accesses the tsp. It shouldn't be too hard to have the TSS entry be
> removed from the list when it is no longer needed. I'll try and get
> round to sorting it for Boost 1.37. If you raise a trac ticket I'll be
> more likely to remember.

Would this work? It seems to fix my problem:

Index: boost/thread/tss.hpp
===================================================================
--- boost/thread/tss.hpp (revisão 46411)
+++ boost/thread/tss.hpp (cópia de trabalho)
@@ -22,6 +22,7 @@
             virtual void operator()(void* data)=0;
         };

+ BOOST_THREAD_DECL void remove_tss_data(void const*
key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool
cleanup_existing);
         BOOST_THREAD_DECL void set_tss_data(void const*
key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool
cleanup_existing);
         BOOST_THREAD_DECL void* get_tss_data(void const* key);
     }
@@ -74,6 +75,7 @@
         ~thread_specific_ptr()
         {
             reset();
+ detail::remove_tss_data(this,cleanup,0,true);
         }

         T* get() const
Index: libs/thread/src/win32/thread.cpp
===================================================================
--- libs/thread/src/win32/thread.cpp (revisão 46411)
+++ libs/thread/src/win32/thread.cpp (cópia de trabalho)
@@ -541,6 +541,40 @@
             }
             return NULL;
         }
+
+ void remove_tss_data(void const*
key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool
cleanup_existing)
+ {
+ tss_cleanup_implemented(); // if anyone uses TSS, we need
the cleanup linked in
+ detail::thread_data_base* const
current_thread_data(get_current_thread_data());
+ if(current_thread_data)
+ {
+ detail::tss_data_node* current_node=current_thread_data->tss_data
+ , *previous_node = 0;
+ while(current_node)
+ {
+ if(current_node->key==key)
+ {
+ // found
+ if(previous_node)
+ {
+ current_node = current_node->next;
+ heap_delete<tss_data_node>(previous_node->next);
+ previous_node->next = current_node;
+ }
+ else
+ {
+ previous_node = current_node;
+ current_node = current_node->next;
+ heap_delete<tss_data_node>(previous_node);
+ current_thread_data->tss_data = current_node;
+ }
+ break;
+ }
+ previous_node = current_node;
+ current_node=current_node->next;
+ }
+ }
+ }

         void set_tss_data(void const*
key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool
cleanup_existing)
         {

> Anthony
> --
> Anthony Williams | Just Software Solutions Ltd
> Custom Software Development | http://www.justsoftwaresolutions.co.uk
> Registered in England, Company Number 5478976.
> Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL

Thanks,

-- 
Felipe Magno de Almeida

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk