
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