# Reader Writer Lock Implementation

I'm practicing to write c++11/14 and I implemented a RW lock. Does everything look ok?

class RWLock {
public:
void readLock() {
std::unique_lock<std::mutex> lock(mutex);
waitingReaders.wait(lock, [this]{!writer && queuedWriters == 0});
++readers;
}

void readUnlock() {
std::unique_lock<std::mutex> lock(mutex);
--readers;
if (readers == 0 && queuedWriters > 0) {
lock.unlock();
waitingWriters.notify_one();
}
}

void writeLock() {
std::unique_lock<std::mutex> lock(mutex);
++queuedWriters;
waitingWriters.wait(lock, [this]{!writer && readers == 0});
--queuedWriters;
writer = true;
}

void writeUnlock() {
std::unique_lock<std::mutex> lock(mutex);

if(queuedWriters > 0) {
lock.unlock();
waitingWriters.notify_one();
} else {
writer = false;
lock.unlock();
waitingReaders.notify_all();
}
}

private:
std::mutex mutex;
std::condition_variable waitingReaders;
std::condition_variable waitingWriters;

int readers = 0;
int queuedWriters = 0;
bool writer = false;
};


In particular: Do I really need to take a lock in my WriteUnlock() method? It looks like all I'm doing is unlock right away.

And is it recommended to perform a lock.unlock() before I do a notify_one or a notify_all ?

Does performing a condition_variable.wait(lock, lambda) where the lambda is true cause a performance loss? Like potentially in the readLock() method

## 1 Answer

Do I really need to take a lock in my WriteUnlock() method? It looks like all I'm doing is unlock right away.

YES, you need the lock, because you are accessing queuedWriters and you need to make sure nobody changes it (by calling writeLock) before you notify readers or writers based on the check. You could have seen queuedWriters being zero, therefore notifying readers, but some writer could get sleeping in the meantime and never get woken.

And is it recommended to perform a lock.unlock() before I do a notify_one or a notify_all?

Unlock before, because the thread being woken would immediatelly try to hold the lock, thus being blocked again (to be woken for second time when you unlock).

Does performing a condition_variable.wait(lock, lambda) where the lambda is true cause a performance loss?

It is same as while (!pred()) wait(lck); What else could you do? It checks first, so, would not wait if the condition is true.

• I have also always wondered if you need to unlock() before a notify*(). But I have never found a reference with this recommendation (for or against). If you have a reference for this I would love to read it. Currently I am not convinced by your logic; just because you notify the conditional does not mean that anything happens immediately. Note: I am not saying it is bad advice (it seems logical and does not seem to break things) but I would love to read from an authoritative reference. – Martin York May 24 '18 at 21:16
• @MartinYork stackoverflow.com/questions/17101922/… – firda May 24 '18 at 22:01