SharedLock.cs
75 lines
| 2.0 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r129 | using System; | ||
using System.Threading; | ||||
using System.Diagnostics; | ||||
namespace Implab.Parallels { | ||||
/// <summary> | ||||
/// Implements a lightweight mechanism to aquire a shared or an exclusive lock. | ||||
/// </summary> | ||||
public class SharedLock { | ||||
readonly object m_lock = new object(); | ||||
int m_locks; | ||||
bool m_exclusive; | ||||
public bool LockExclusive(int timeout) { | ||||
lock (m_lock) { | ||||
if (m_locks > 0 && !Monitor.Wait(m_lock, timeout)) | ||||
return false; | ||||
m_exclusive = true; | ||||
m_locks = 1; | ||||
} | ||||
} | ||||
public void LockExclusive() { | ||||
LockExclusive(-1); | ||||
} | ||||
public bool LockShared(int timeout) { | ||||
lock (m_lock) { | ||||
if (!m_exclusive) { | ||||
m_locks++; | ||||
return true; | ||||
} | ||||
if (m_lock == 0) { | ||||
m_exclusive = false; | ||||
m_locks = 1; | ||||
return true; | ||||
} | ||||
if (Monitor.Wait(m_lock, timeout)) { | ||||
Debug.Assert(m_locks == 0); | ||||
m_locks = 1; | ||||
m_exclusive = false; | ||||
return true; | ||||
} | ||||
return false; | ||||
} | ||||
} | ||||
public void LockShared() { | ||||
LockShared(-1); | ||||
} | ||||
public void ReleaseShared() { | ||||
lock (m_lock) { | ||||
if (m_exclusive || m_locks <= 0) | ||||
throw new InvalidOperationException(); | ||||
m_locks--; | ||||
if (m_locks == 0) | ||||
Monitor.PulseAll(m_lock); | ||||
} | ||||
} | ||||
public void ReleaseExclusive() { | ||||
lock (m_lock) { | ||||
if (!m_exclusive && m_locks != 1) | ||||
throw new InvalidOperationException(); | ||||
m_locks = 0; | ||||
Monitor.PulseAll(m_lock); | ||||
} | ||||
} | ||||
} | ||||
} | ||||