Boost logo

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