// // Author: Carson Jones // Adapted from "Art of Multiprocessor Programming" by Herlihy and Shavit // CS6966 // using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ReadWriteLock { /// /// The main ReadWriteLock class. /// public class FifoReadWriteLock : IReadWriteLock { private static int readers; private static bool writer; static Mutex rwlock; private ILock readLock; private ILock writeLock; public FifoReadWriteLock() { writer = false; readers = 0; rwlock = new Mutex(); readLock = new ReadLock(); writeLock = new WriteLock(); } public ILock GetReadLock() { return readLock; } public ILock GetWriteLock() { return writeLock; } /// /// Inner class for ReadLock. /// private class ReadLock : ILock { /// /// Locks the read lock. If there is some writer writing, this method waits until the writer signals (pulses). /// public void Lock() { lock (rwlock) { while (writer) { Monitor.Wait(rwlock); } readers++; } } /// /// Unlocks the read lock. If there are no readers, this method will pulse the writer condition to let writers know they can proceed. /// public void Unlock() { lock (rwlock) { readers--; if (readers == 0) Monitor.PulseAll(rwlock); } } } /// /// Inner class for WriteLock /// private class WriteLock : ILock { /// /// Locks the write lock. If there are any readers, this method waits until they finish. /// public void Lock() { lock (rwlock) { writer = true; while (readers > 0) { Monitor.Wait(rwlock); } } } /// /// Unlocks the write lock. This method also pulses all waiting reader threads to signal them that data is available. /// public void Unlock() { lock (rwlock) { writer = false; Monitor.PulseAll(rwlock); } } } } }