
On Mar 21, 2007, at 5:20 PM, Yuval Ronen wrote:
Makes a lot of sense. Makes me wonder why the mutexes in N2094 are not movable also.
I actually thought about that. My inclination is to model pthreads (which also appears to have been the boost inclination). And pthread_mutex_t does not appear to be a copyable item. And I'm wanting to be able to implement like this: class mutex { pthread_mutex_t mut_; public: ... }; as opposed to: class mutex { pthread_mutex_t* mut_; // on heap public: ... }; It appears that a pthread implementation is allowed to point into a pthread_mutex_t and thus copy/moving it becomes problematic. To alleviate this, N2094 does make the locks movable. The locks simply have a pointer to the mutex. The pointer controls (owns) the locked status of the mutex, not the lifetime of it though. The usual idiom is to have the mutex at namespace scope, or as a class data member, and have the lock referring to that mutex "on the stack". So for the usual idioms, non-copyable, non-movable mutexes do not seem overly problematic. In contrast, pthread_t is clearly copyable. pthread_t pthread_self(); However the semantics of pthread_t when looked at through a C++ lens is: sole ownership. * A pthread_t initialized from pthread_create, must be joined or detached exactly once. And a non-guaranteed but common implementation of pthread_t is as simply a pointer to some opaque struct. Therefore a movable pthread_t wrapper is quite practical: class thread { pthread_t thr_; thread(const thread&); thread& operator=(const thread&); public: thread(thread&& t) : thr_(t.thr_) {t.thr_ = 0;} thread& operator=(thread&& t) { if (joinable()) // is thr_ == 0 { cancel(); detach(); // sets thr_ = 0 }; thr_ = t.thr_; t.thr_ = 0; return *this; } ... }; And this conceptual view appears to be implementable on Windows too (thanks again Anthony!). Perhaps if I get the chance to revise N2094 I should include the above motivation for this choice explicitly (and thanks).
* N2184::thread separates out the concept of thread identity and thread handle. In boost these are both just boost::thread. The thread::id is copyable. The only thing you can do with it is equality compare it.
I think we might want it to be OutStreamable also. Mainly for debugging and logging purposes.
Good suggestion, thanks. -Howard