
On Nov 2, 2006, at 3:23 AM, Anthony Williams wrote:
Agreed. So we would end up with mutex and recursive_mutex, yes?
Yes, though I like Howard's idea of recursive_mutex being an adaptor, with specializations for optimization.
Btw, recursive_mutex adaptor, if it is a good idea in the first place, is a good example of an application needing to lock a mutex in a non-scoped manner. Ion pointed out to me that recursive_mutex shouldn't hold a mutex&, but rather a mutex. It can then be constructed in place with perfectly forwarding variadic templates: template <class Mutex> class recursive_mutex { private: Mutex mut_; unsigned count_; thread_util::id id_; public: template <class ...T> explicit recursive_mutex(T&& t...) : mut_(std::forward<T>(t)...), count_(0), id_ (thread_self::not_any_thread()) {} I probably messed up the variadic template syntax. But this way you don't have to have an external mutex sitting out somewhere, but if you want that you can use recurisive_mutex<mutex&> (which could also be specialized as a straight drop through if need be). This is of course somewhat emulate-able in C++03 (like bind does). I should also stress: recursive_mutex is an experiment, not a proposed solution. I'm just thinking out loud, and would like more help in the thinking department. :-)
I was thinking about mutex, try_mutex and timed_mutex, which I think can really be one and the same class.
I've also been experimenting with a timed_mutex adaptor: <experimental> struct event { mutex mut_; condition<mutex> cond_; }; template <class Mutex> class timed_mutex { private: Mutex mut_; event sig_; timespec abs_time_; timed_mutex(const timed_mutex&); timed_mutex& operator=(const timed_mutex&); public: template <class ...T> timed_mutex(T&& t..., const timespec& abs_time) : mut_(std::forward<T>(t)...), abs_time_(abs_time)) {} void lock() { mut_.lock(); } bool try_lock() { exclusive_lock<mutex> lk(sig_.mut_); bool timed_out; bool owns; do { owns = mut_.try_lock(); if (owns) break; timed_out = !sig_.cond_.timed_wait(sig_.mut_, abs_time_); } while (!timed_out); return owns; } void unlock() { mut_.unlock(); sig_.cond_.notify_all(); } }; </experimental> This is even less mature than the recursive_mutex. But hopefully people can see where I'm trying to go: Instead of having recursive and timed flavors of every kind of mutex (exclusive, sharable, upgradable), one might instead have adaptors that one could apply to these, and perhaps to user-defined mutexes as well (more motivation for mutex concepts: here's more generic mutex code people could plug into). -Howard