Mercurial > pub > ImplabNet
view Implab/Parallels/SharedLock.cs @ 131:b5c2d609d71b v2
minor changes
author | cin |
---|---|
date | Sat, 07 Feb 2015 11:06:42 +0300 |
parents | 671f60cd0250 |
children | e9e7940c7d98 |
line wrap: on
line source
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; return true; } } public void LockExclusive() { LockExclusive(-1); } public bool LockShared(int timeout) { lock (m_lock) { if (!m_exclusive) { m_locks++; return true; } if (m_locks == 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); } } } }