Mercurial > pub > ImplabNet
view Implab/Parallels/SharedLock.cs @ 134:04d4c92d0f28 v2
Improved logging
author | cin |
---|---|
date | Wed, 11 Feb 2015 02:12:15 +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); } } } }