Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2007-03-27 11:17:12


On Mar 27, 2007, at 10:21 AM, Peter Dimov wrote:

> In implementation terms:
>
> class thread
> {
> pthread_t handle_;
> bool detached_;
>
> public:
>
> thread(): detached_( false ) {}
>
> void detach() { atomic_store( &detached_, true ); }
>
> // (try-/timed-) 'const' joins
>
> ~thread()
> {
> if( !detached_ ) cancel();
> pthread_detach( handle_ );
> }
> };
>
> Is this not a conforming N2184 thread? If not, why?

Thanks for the pseudo code. I was working on pseudo code to show as
well but I'm an hour behind you. Below is *pseudo* code. I've
ignored the necessary atomics among other details in an effort for
clarity (hopefully I haven't ignored so much as to make it
confusing). Comments attempt to illuminate our differences. I
believe one of the big differences is : How soon after join() can the
thread clean up resources? I.e. the model I've been working on has an
implicit detach() inside of join(), for the purpose of cleaning up the
resources immediately instead of waiting to ~thread() for resource
cleanup.

My apologies in advance for the inappropriate wrapping. I've tried to
keep my line lengths very short...

pthread_t handle_;
thread_local_data* tl;

detach()
{
     // If has already been detached, that means tl may already be
released
     // therefore not safe to go through twice.
     // But maybe ok to ignore subsequent detach?
     if (handle_ == 0)
         throw ?;
     tl->wait_on_owner = false;
     tl->cv2.notify_all();
     handle_ = 0;
}

cancel()
{
     // Canceling a non-existent thread seems harmless
     if (handle_ != 0)
         tl->cancel_pending = true;
}

join()
{
     // Don't want to pretend to join with non-existent
     // (or detached) thread, make noise
     if (handle_ == 0)
         throw ?;
     while (!tl->done)
         tl->cv1.wait();
     detach(); // point of contention with N2178, makes join non-const,
                // and disables multi-join. Without it, resources not
                // released until explicit detach() or ~thread()
}

~thread()
{
     if (handle_ != 0)
     {
         cancel(); // harmless if already canceled
         detach(); // we haven't detached or joined yet else handle_
is 0
     }
}

start()
{
     allocate_all_resources(); // tl != 0
     tl->done = false;
     tl->wait_on_owner = true;
     tl->cancel_pending = false;
     try
     {
         f();
     }
     catch (thread_canceled&)
     {
     }
     catch (...)
     {
         terminate();
     }
     tl->done = true;
     tl->cv1.notify_all();
     while (tl->wait_on_owner)
         tl->cv2.wait();
     release_all_resources(); // tl = 0
}

-Howard


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