C++0x is getting multithreading support, and that support includes a new type called condition_variable_any:
class condition_variable_any
{
public:
condition_variable_any();
~condition_variable_any();
condition_variable_any(const condition_variable_any&) = delete;
condition_variable_any& operator=(const condition_variable_any&) = delete;
void notify_one();
void notify_all();
template <class Lock>
void wait(Lock& lock);
template <class Lock, class Predicate>
void wait(Lock& lock, Predicate pred);
template <class Lock, class Clock, class Duration>
cv_status
wait_until(Lock& lock,
const chrono::time_point<Clock, Duration>& abs_time);
template <class Lock, class Clock, class Duration, class Predicate>
bool
wait_until(Lock& lock,
const chrono::time_point<Clock, Duration>& abs_time,
Predicate pred);
template <class Lock, class Rep, class Period>
cv_status
wait_for(Lock& lock,
const chrono::duration<Rep, Period>& rel_time);
template <class Lock, class Rep, class Period, class Predicate>
bool
wait_for(Lock& lock,
const chrono::duration<Rep, Period>& rel_time,
Predicate pred);
};
There is an explanation of how to implement condition_variable_any here:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html#gen_cond_var
but at this link it is named gen_cond_var. The magic thing about condition_variable_any is that it will wait on anything that has lock() and unlock() members. Once you have condition_variable_any, then all you need is a rwlock. The link above also introduces shared_mutex and shared_lock and shows example code doing what you want:
std::tr2::shared_mutex mut;
std::gen_cond_var cv;
void wait_in_shared_ownership_mode()
{
std::tr2::shared_lock<std::tr2::shared_mutex> shared_lk(mut);
// mut is now shared-locked
// ...
while (not_ready_to_proceed())
cv.wait(shared_lk); // shared-lock released while waiting
// mut is now shared-locked
// ...
} // mut is now unlocked
void wait_in_unique_ownership_mode()
{
std::unique_lock<std::tr2::shared_mutex> lk(mut);
// mut is now unique-locked
// ...
while (not_ready_to_proceed())
cv.wait(lk); // unique-lock released while waiting
// mut is now unique-locked
// ...
} // mut is now unlocked
The above document is somewhat dated. There is a more up-to-date implementation and description of shared_mutex / shared_lock here:
http://howardhinnant.github.io/shared_mutex http://howardhinnant.github.io/shared_mutex.cpp
All of this is implemented on top of POSIX pthreads. I hope to get the shared-locking stuff into a C++ technical report (tr2), but of course there is no guarantee of that.