Mercurial > pub > ImplabNet
comparison Implab/Parallels/SharedLock.cs @ 129:471f596b2603 v2
Added SharedLock to synchronization routines
author | cin |
---|---|
date | Thu, 29 Jan 2015 18:31:06 +0300 |
parents | |
children | 671f60cd0250 |
comparison
equal
deleted
inserted
replaced
128:6241bff0cd64 | 129:471f596b2603 |
---|---|
1 using System; | |
2 using System.Threading; | |
3 using System.Diagnostics; | |
4 | |
5 namespace Implab.Parallels { | |
6 /// <summary> | |
7 /// Implements a lightweight mechanism to aquire a shared or an exclusive lock. | |
8 /// </summary> | |
9 public class SharedLock { | |
10 readonly object m_lock = new object(); | |
11 int m_locks; | |
12 bool m_exclusive; | |
13 | |
14 public bool LockExclusive(int timeout) { | |
15 lock (m_lock) { | |
16 if (m_locks > 0 && !Monitor.Wait(m_lock, timeout)) | |
17 return false; | |
18 m_exclusive = true; | |
19 m_locks = 1; | |
20 } | |
21 } | |
22 | |
23 public void LockExclusive() { | |
24 LockExclusive(-1); | |
25 } | |
26 | |
27 public bool LockShared(int timeout) { | |
28 lock (m_lock) { | |
29 if (!m_exclusive) { | |
30 m_locks++; | |
31 return true; | |
32 } | |
33 | |
34 if (m_lock == 0) { | |
35 m_exclusive = false; | |
36 m_locks = 1; | |
37 return true; | |
38 } | |
39 | |
40 if (Monitor.Wait(m_lock, timeout)) { | |
41 Debug.Assert(m_locks == 0); | |
42 m_locks = 1; | |
43 m_exclusive = false; | |
44 return true; | |
45 } | |
46 return false; | |
47 } | |
48 } | |
49 | |
50 public void LockShared() { | |
51 LockShared(-1); | |
52 } | |
53 | |
54 public void ReleaseShared() { | |
55 lock (m_lock) { | |
56 if (m_exclusive || m_locks <= 0) | |
57 throw new InvalidOperationException(); | |
58 m_locks--; | |
59 if (m_locks == 0) | |
60 Monitor.PulseAll(m_lock); | |
61 } | |
62 } | |
63 | |
64 public void ReleaseExclusive() { | |
65 lock (m_lock) { | |
66 if (!m_exclusive && m_locks != 1) | |
67 throw new InvalidOperationException(); | |
68 m_locks = 0; | |
69 Monitor.PulseAll(m_lock); | |
70 } | |
71 } | |
72 | |
73 } | |
74 } | |
75 |