129
|
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
|