|
Boost : |
From: Batov, Vladimir (Vladimir.Batov_at_[hidden])
Date: 2004-06-27 16:38:23
RW mutexes/locks are important to a threading library and appear simple
to implement. However, Boost.Threads lacks it. I wrote something simple
that appear to do the job using the functionality already available in
Boost.Threads. If the idea is considered good/robust/efficient enough
and worth having in the library, I can re-write it to conform with the
rest of Boost.Threads.
class rw_mutex : private boost::noncopyable
{
typedef boost::condition Condition;
public:
friend class writer_lock;
friend class reader_lock;
rw_mutex() : num_readers_(0), num_writers_(0) {}
private:
boost::mutex mutex_;
Condition reader_condition_;
Condition writer_condition_;
int num_readers_;
int num_writers_;
};
class writer_lock : public boost::mutex::scoped_lock
{
typedef boost::mutex::scoped_lock super;
public:
writer_lock(rw_mutex& mutex) : super(mutex.mutex_), mutex_(mutex)
{
++mutex_.num_writers_; // Make new readers wait.
// If there are readers in-progress, wait for them to finish.
while (mutex_.num_readers_)
mutex_.writer_condition_.wait(*this);
}
~writer_lock()
{
--mutex_.num_writers_;
// Last writer notifies waiting readers.
// If not last, wake up the next writer.
if (!mutex_.num_writers_) mutex_.reader_condition_.notify_all();
else mutex_.writer_condition_.notify_one();
}
private:
rw_mutex& mutex_;
};
class reader_lock : public boost::mutex::scoped_lock
{
typedef boost::mutex::scoped_lock super;
public:
reader_lock(rw_mutex& mutex) : super(mutex.mutex_), mutex_(mutex)
{
// If there are writers waiting, let them in first.
while (mutex_.num_writers_)
mutex_.reader_condition_.wait(*this);
++mutex_.num_readers_; // Make new writes wait.
unlock();
}
~reader_lock()
{
lock();
--mutex_.num_readers_;
// Last reader notifies
if (!mutex_.num_readers_) mutex_.writer_condition_.notify_one();
}
private:
rw_mutex& mutex_;
};
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk