1
2
3
4
5
6 using System;
7
8 namespace System.Threading
9 {
10 public enum ConditionVariableStatus : int
11 {
12 timeout = 0, no_timeout = 1
13 }
14
15 public delegate bool Predicate(void* arg);
16 public class delegate bool PredicateMethod(void* arg);
17
18 public class ConditionVariable
19 {
20 public nothrow ConditionVariable() : nativeHandle(RtAllocateConditionVariable())
21 {
22 }
23 public ~ConditionVariable()
24 {
25 if (nativeHandle != null)
26 {
27 RtFreeConditionVariable(nativeHandle);
28 }
29 }
30 suppress ConditionVariable(const ConditionVariable&);
31 suppress void operator=(ConditionVariable&);
32 public nothrow ConditionVariable(ConditionVariable&& that) : nativeHandle(that.nativeHandle)
33 {
34 that.nativeHandle = null;
35 }
36 public nothrow void operator=(ConditionVariable&& that)
37 {
38 Swap(nativeHandle, that.nativeHandle);
39 }
40 public void NotifyOne()
41 {
42 int result = RtNotifyOne(nativeHandle);
43 if (result < 0)
44 {
45 string message = RtGetError(result);
46 RtDisposeError(result);
47 throw ThreadingException(message);
48 }
49 }
50 public void NotifyAll()
51 {
52 int result = RtNotifyAll(nativeHandle);
53 if (result < 0)
54 {
55 string message = RtGetError(result);
56 RtDisposeError(result);
57 throw ThreadingException(message);
58 }
59 }
60 public void Wait(RecursiveMutex& mtx)
61 {
62 int result = RtWaitConditionVariable(nativeHandle, mtx.NativeHandle());
63 if (result < 0)
64 {
65 string message = RtGetError(result);
66 RtDisposeError(result);
67 throw ThreadingException(message);
68 }
69 }
70 public ConditionVariableStatus WaitFor(RecursiveMutex& mtx, const Duration& duration)
71 {
72 int result = RtWaitConditionVariableDuration(nativeHandle, mtx.NativeHandle(), duration.Rep());
73 if (result < 0)
74 {
75 string message = RtGetError(result);
76 RtDisposeError(result);
77 throw ThreadingException(message);
78 }
79 return cast<ConditionVariableStatus>(result);
80 }
81 public ConditionVariableStatus WaitUntil(RecursiveMutex& mtx, const TimePoint& tp)
82 {
83 Duration duration = tp - Now();
84 return WaitFor(mtx, duration);
85 }
86 public void Wait(RecursiveMutex& mtx, Predicate predicate, void* arg)
87 {
88 while (!predicate(arg))
89 {
90 Wait(mtx);
91 }
92 }
93 public bool WaitFor(RecursiveMutex& mtx, Predicate predicate, void* arg, const Duration& duration)
94 {
95 while (!predicate(arg))
96 {
97 if (WaitFor(mtx, duration) == ConditionVariableStatus.timeout)
98 {
99 return predicate(arg);
100 }
101 }
102 return true;
103 }
104 public bool WaitUntil(RecursiveMutex& mtx, Predicate predicate, void* arg, const TimePoint& tp)
105 {
106 Duration duration = tp - Now();
107 return WaitFor(mtx, predicate, arg, duration);
108 }
109 public void Wait(RecursiveMutex& mtx, PredicateMethod predicateMethod, void* arg)
110 {
111 while (!predicateMethod(arg))
112 {
113 Wait(mtx);
114 }
115 }
116 public bool WaitFor(RecursiveMutex& mtx, PredicateMethod predicateMethod, void* arg, const Duration& duration)
117 {
118 while (!predicateMethod(arg))
119 {
120 if (WaitFor(mtx, duration) == ConditionVariableStatus.timeout)
121 {
122 return predicateMethod(arg);
123 }
124 }
125 return true;
126 }
127 public bool WaitUntil(RecursiveMutex& mtx, PredicateMethod predicateMethod, void* arg, const TimePoint& tp)
128 {
129 Duration duration = tp - Now();
130 return WaitFor(mtx, predicateMethod, arg, duration);
131 }
132 private void* nativeHandle;
133 }
134 }