Skip to content

Commit

Permalink
[Util] Close #210: Implement R/W locking.
Browse files Browse the repository at this point in the history
Implements a many-readers single-writer locking scheme with the support
for one reader to atomically upgrade to a writer.

Many readers can concurrently read a shared resource.  If a writer wants
to access the resource, it requests a write lock.  Further readers must
wait for the writer to complete.  Still active readers are not
interrupted and must unlock their read locks eventually.  A writer can
then claim the exclusive write lock.

A reader can *attempt* to upgrade to a writer in an atomic operation,
i.e. w/o releasing its read lock first.  However, that operation fails
if another reader has requested an upgrade already and was not yet
granted the write lock.  If the attempt to upgrade fails, the reader
should release its held read lock to prevent deadlocks.  This behavior
is implemented by `reader_writer_lock` and `upgrade_lock`.  Through
direct use of `reader_writer_mutex`, though, one can cause a deadlock.

If the attempt to upgrade fails, and the read lock is consequently
unlocked, the reader can retry by reclaiming a read lock, re-reading the
shared resource, and then reattempting to upgrade.  A good idiom for
this scheme is:

```cpp
m::upgrade_lock lock{rw_mutex, std::defer_lock};
m::write_lock wlock{rw_mutex, std::defer_lock};

do {
    lock.lock();
    // read from shared resource
} while (wlock = lock.upgrade(), not wlock.owns_lock());
// modify resource, that is now exclusively locked
wlock.unlock();
```

It may be simpler to use a single `reader_writer_lock`, but for the sake
of completeness and to mimic STL and Boost, we provide `read_lock`,
`write_lock`, and `upgrade_lock`.
  • Loading branch information
ImmanuelHaffner committed Jan 25, 2024
1 parent 6df2e44 commit f83dbd0
Show file tree
Hide file tree
Showing 3 changed files with 695 additions and 1 deletion.
Loading

0 comments on commit f83dbd0

Please sign in to comment.