I have adopted an implementation of a simple (without updates or timeouts) ReaderWriterLock for Silverlight, I was wondering if anyone who has rights can confirm if this is good or bad in design. It looks pretty good to me, it works as advertised, but I have limited experience with using multi-threaded code as such.
public sealed class ReaderWriterLock
{
private readonly object syncRoot = new object();
private int i = 0;
private int readWaiters = 0;
private int writeWaiters = 0;
private ConditionVariable conditionVar;
public ReaderWriterLock()
{
conditionVar = new ConditionVariable(syncRoot);
}
public bool IsReaderLockHeld
{
get
{
lock ( syncRoot )
{
if ( i > 0 )
return true;
return false;
}
}
}
public bool IsWriterLockHeld
{
get
{
lock ( syncRoot )
{
if ( i < 0 )
return true;
return false;
}
}
}
public void AcquireWriterLock()
{
lock ( syncRoot )
{
writeWaiters++;
while ( i != 0 )
conditionVar.Wait();
writeWaiters--;
i = -1;
}
}
public void AcquireReaderLock()
{
lock ( syncRoot )
{
readWaiters++;
if ( writeWaiters > 0 )
{
conditionVar.Pulse();
Monitor.Wait(syncRoot);
}
while ( i < 0 )
Monitor.Wait(syncRoot);
readWaiters--;
i++;
}
}
public void ReleaseWriterLock()
{
bool doPulse = false;
lock ( syncRoot )
{
i = 0;
if ( readWaiters > 0 )
{
Monitor.PulseAll(syncRoot);
}
else
{
doPulse = true;
}
}
if ( doPulse )
conditionVar.Pulse();
}
public void ReleaseReaderLock()
{
bool doPulse = false;
lock ( syncRoot )
{
i--;
if ( i == 0 )
doPulse = true;
}
if ( doPulse )
conditionVar.Pulse();
}
public class ConditionVariable
{
private readonly object syncLock = new object();
private readonly object m;
public ConditionVariable(object m)
{
lock (syncLock)
{
this.m = m;
}
}
public void Wait()
{
bool enter = false;
try
{
lock (syncLock)
{
Monitor.Exit(m);
enter = true;
Monitor.Wait(syncLock);
}
}
finally
{
if (enter)
Monitor.Enter(m);
}
}
public void Pulse()
{
lock (syncLock)
{
Monitor.Pulse(syncLock);
}
}
public void PulseAll()
{
lock (syncLock)
{
Monitor.PulseAll(syncLock);
}
}
}
}
If this is good, it may be useful for others, as Silverlight does not currently have a read / write lock type. Thanks.
Rishi
source
share