|
Boost : |
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2007-03-27 12:33:13
On Mar 27, 2007, at 11:47 AM, Peter Dimov wrote:
>
>> 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()
>> }
>>
> ... we can still remove this detach() call from join() and the user
> is free
> to get the old semantics back by just calling detach() explicitly
> after
> join() (whereas the reverse is not true).
Ok, I'm still having pain from realloc doing too much. :-) Maybe this
is a safe spot to tweak the pthreads semantics since ~thread() *must*
catch any leaks and C doesn't have that option. I've tweaked the
pseudo code as below and am continuing to look for problems with it.
I believe this comes closer to Anthony's earlier post. And note the
const qualifier I put on join!!! :-) (reserving the right to waffle
back...)
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)
{
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() const
{
// 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();
}
thread::id get_id() const {return thread::id(handle_);}
~thread()
{
cancel(); // harmless if already canceled
detach(); // harmless if already detached
}
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