//
// 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);
}
}
}
}
}