
Howard Hinnant wrote:
I'm coming full circle...
As soon as I start allowing multiple threads to access std::thread at once, I need to keep a mutex around for the lifetime of the std::thread, whether or not it is already joined or even detached:
[...] Here's how one possible N2184 thread looks to me: class thread { private: n2178::handle handle_; thread( thread const & ); thread& operator=( thread const & ); public: thread() {} template<class F> explicit thread( F f ): handle_( n2178::create( f ) ) {} thread( thread && rhs ): handle_( std::move( rhs.handle_ ) ) { } thread& operator=( thread && rhs ) { handle_ = std::move( rhs.handle_ ); return *this; } void swap( thread& rhs ) { handle_.swap( rhs.handle_ ); } void join() const { n2178::join( handle_ ); } bool try_join() const { return n2178::try_join( handle_ ) != EBUSY; } bool timed_join( timespec const & abstime ) const { return n2178::timed_join( handle_, abstime ) != ETIMEDOUT; } void cancel() // const acc. to taste { n2178::cancel( handle_ ); } }; For cancel on destroy, add: bool cancel_on_destroy_; // initially true ~thread() { if( cancel_on_destroy_ ) cancel(); } void detach() { atomic_store( &cancel_on_destroy_, true ); } There appears to be no need for a mutex in this prototype, unless I've missed something. Even if the actual implementation uses no n2178::handle, the above sketch might still be useful as an illustration of the semantics and thread safety that I have in mind. The omission of joinable() and cancel_requested() is intentional, the omission of the rest of the members is for brevity, although hardware_concurrency would probably be better off as a free function. To get back to an earlier statement of yours:
This just leaves me with the feeling of implementing unique_ptr in terms of shared_ptr, at least on a pthreads platform.
Under my implementation at least, it's more like implementing intrusive_ptr<thread_data> where the refcount can be at most 2 (std::thread and the thread itself both holding a ref) in terms of intrusive_ptr<thread_handle> with no refcount limit.