Boost logo

Boost :

Subject: Re: [boost] [thread] reset a thread_specific_ptr by this pointer
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2008-12-12 18:05:40


----- Original Message -----
From: "Pengcheng Song" <pengcheng.simon_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, December 12, 2008 10:34 PM
Subject: [boost] [thread] reset a thread_specific_ptr by this pointer

>
>
> Hi All,
> I was experimenting with the boost.threads library and especially
> boost::thread_specific_ptr. However, I ran into problems trying to reset the
> thread_specific_ptr by the this pointer (see the code below).
>
>
> // ========= beginning of code =============
> #include <iostream>
> #include <boost/thread/thread.hpp>
> #include <boost/thread/mutex.hpp>
> #include <boost/thread/tss.hpp>
>
> boost::mutex mutex_;
>
> class A
> {
> private:
> double x_;
> static boost::thread_specific_ptr ptr_;
> public:
> A(double x=0) : x_(x)
> {}
>
> void operator()()
> {
> if (0==ptr_.get()) {
> ptr_.reset(this);
> }
> boost::mutex::scoped_lock lock(mutex_);
> std::cout << "x_=" << x_ << std::endl;
> }
> };
>
> boost::thread_specific_ptr A::ptr_;
>
> int main()
> {
> boost::thread thrd1( A(1) );
> boost::thread thrd2( A(2) );
> thrd1.join();
> thrd2.join();
> return 0;
> }
> // ======= end of code =========
>
> This compiled fine with boost_1_36 (binary from boostPro) under VC9 with
> multithreaded debug DLL code generation. But when I ran it under the debug
> mode, I got the following error message:
>
> Debug Assertion Failed.
> Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
>
> I searched the web and this seemed to be a memory problem. And I noticed
> that it failed to call the destructor of thread_specific_ptr.
>
> Is my code legal? Or one is not supposed to reset a thread_specific_ptr to
> this pointer? Your feedback would be greatly appreciated.

Hi,

You can use this but thread_specific_ptr owns by default the pointer,so the cleanup default function will use delete which is not correct in your case. If you want to do that you need to construct the thread_specific_ptr using the following prototype,
    explicit thread_specific_ptr(void (*cleanup_function)(T*));
and giving a do nothing cleanup function as parameter.
    void do_nothing(A*) {}
    boost::thread_specific_ptr<A> A::ptr_(do_nothing);

You can add some traces on the A destructor and on the do_nothing cleanup to understand how this work. Be carefull to dont use the parameter passed to do_nothing ( I don't know if it is already destroyed!!)

BTW, does the following line compile?
    static boost::thread_specific_ptr ptr_;
It should be
    static boost::thread_specific_ptr<A> ptr_;

Good luck,
Vicente


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