Provides a fair RWLock, similar to one from Java, which is itself
documented at
http://download.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html
There are complicated policy choices that have to be made. The policy
choices here are different from the ones for the RWLock in
concurrent-extras.
The
FairRWLock may be in a free unlocked state, it may be in
a read locked state, or it may be a write locked state. Many running
threads may hold the read lock and execute concurrently. Only one
running thread may hold the write lock. The scheduling is a fair FIFO
queue that avoids starvation.
When in the read lock state the first
acquireWrite will block,
and subsequent
acquireRead and
acquireWrite will queue
in order. When in the write locked state all other threads trying to
acquireWrite or
acquireRead will queue in order.
FairRWLock allows recursive write locks, and it allows
recursive read locks, and it allows the write lock holding thread to
acquire read locks. When the current writer also holds read locks and
then releases its last write lock it will immediately convert to the
read locked state (and other waiting readers may join it). When a
reader acquires a write lock it will (1) release all its read locks,
(2) wait to acquire the write lock, (3) retake the same number of read
locks released in (1).
The preferred way to use this API is sticking to
new,
withRead, and
withWrite.
No sequence of calling acquire on a single RWLock should lead to
deadlock. Exceptions, espcially from
killThread, do not break
withRead or
withWrite. The
withRead and
withWrite ensure all locks get released when exiting due to an
exception.
The readers and writers are always identified by their
ThreadId. Each thread that calls
acquireRead must later
call
releaseRead from the same thread. Each thread that calls
acquireWrite must later call
releaseWrite from the same
thread. The main way to misuse a FairRWLock is to call a release
without having called an acquire. This is reported in the (Left error)
outcomes from
releaseRead and
releaseWrite. Only if the
FairRWLock has a bug and finds itself in an impossible state
then it will throw an error.