source: trunk/ab5.0/ablib/src/Classes/System/Threading/WaitHandle.ab@ 664

Last change on this file since 664 was 599, checked in by イグトランス (egtra), 16 years ago

ThreadPoolの実装、WaitHandle.WaitAny/WaitAllのまともな実装、ほか。

File size: 6.6 KB
Line 
1' Classes/System/Threading/WaitHandle.ab
2
3Namespace System
4Namespace Threading
5
6Namespace Detail
7 TypeDef PFNSignalObjectAndWait = *Function(hObjectToSignal As HANDLE, hObjectToWaitOn As HANDLE, dwMilliseconds As DWord, bAlertable As DWord) As DWord
8End Namespace
9
10Class WaitHandle
11 Implements System.IDisposable
12Public
13 ' Properties
14' Const Function SafeWaitHandle() As SafeWaitHandle
15' Sub SafeWaitHandle(h As SafeWaitHandle)
16
17 Const Virtual Function Handle() As HANDLE
18 Return h
19 End Function
20
21 Virtual Sub Handle(newHandle As HANDLE)
22 h = newHandle
23 End Sub
24
25 ' Methods
26 Sub WaitHandle()
27 End Sub
28
29 Virtual Sub ~WaitHandle()
30 This.Dispose()
31 End Sub
32
33 Virtual Sub Close()
34 This.Dispose()
35 End Sub
36
37 Virtual Sub Dispose()
38 Dim hDisposing = InterlockedExchangePointer(h, 0)
39 If hDisposing <> 0 Then
40 CloseHandle(hDisposing)
41 End If
42 End Sub
43
44 Function WaitOne() As Boolean
45 Return WaitOne(INFINITE As DWord)
46 End Function
47
48 Function WaitOne(millisecondsTimeout As DWord) As Boolean
49 If h = 0 Then
50 Throw New ObjectDisposedException("WaitHandle.WaitOne")
51 End If
52 Return afterWait(WaitForSingleObject(h, millisecondsTimeout As DWord), 1)
53 End Function
54
55 Function WaitOne(millisecondsTimeout As Long) As Boolean
56 ThrowIfInvalidLongValue(millisecondsTimeout)
57 Return WaitOne(millisecondsTimeout As DWord)
58 End Function
59
60 Function WaitOne(timeout As System.TimeSpan) As Boolean
61 Return WaitOne(timeout.TotalMilliseconds() As Long)
62 End Function
63
64 Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>) As Boolean
65 Return waitImpl(handles, TRUE, INFINITE As DWord)
66 End Function
67
68 Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As Long) As Boolean
69 ThrowIfInvalidLongValue(millisecondsTimeout)
70 Return waitImpl(handles, TRUE, millisecondsTimeout As DWord)
71 End Function
72
73 Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As DWord) As Boolean
74 Return waitImpl(handles, TRUE, millisecondsTimeout)
75 End Function
76
77 Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, timeout As System.TimeSpan) As Boolean
78 Return WaitAny(handles, timeout.TotalMilliseconds() As Long)
79 End Function
80
81 Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>) As Boolean
82 Return waitImpl(handles, FALSE, INFINITE As DWord)
83 End Function
84
85 Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As Long) As Boolean
86 ThrowIfInvalidLongValue(millisecondsTimeout)
87 Return waitImpl(handles, FALSE, millisecondsTimeout As DWord)
88 End Function
89
90 Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As DWord) As Boolean
91 Return waitImpl(handles, FALSE, millisecondsTimeout)
92 End Function
93
94 Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>, timeout As System.TimeSpan) As Boolean
95 Return WaitAny(handles, timeout.TotalMilliseconds() As Long)
96 End Function
97
98 Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle) As Boolean
99 Return SignalAndWait(toSignal, toWaitOn, INFINITE)
100 End Function
101
102 Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As System.TimeSpan) As Boolean
103 Return SignalAndWait(toSignal, toWaitOn, timeout.TotalMilliseconds() As Long)
104 End Function
105
106 Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As Long) As Boolean
107 Return SignalAndWait(toSignal, toWaitOn, timeout As DWord)
108 End Function
109
110 Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, millisecondsTimeout As DWord) As Boolean
111 Dim pSignalObjectAndWait = GetProcAddress(GetModuleHandle("Kernel32.dll"), ToMBStr("SignalObjectAndWait")) As Detail.PFNSignalObjectAndWait
112 If pSignalObjectAndWait = 0 Then
113 Throw New PlatformNotSupportedException("WaitHandle.SignalAndWait: This platform doesn't supoort this operation.")
114 End If
115 Return afterWait(pSignalObjectAndWait(toSignal.Handle, toWaitOn.Handle, millisecondsTimeout As DWord, FALSE), 1)
116 End Function
117
118 Static Const WaitTimeout = WAIT_TIMEOUT
119
120Protected
121 Static Const InvalidHandle = INVALID_HANDLE_VALUE As HANDLE
122
123Private
124 h As HANDLE
125
126 /*!
127 @brief WaitAll/WaitAnyの実装
128 @param[in] handles 待機ハンドル
129 @param[in] waitAll WaitAllならTRUE、WaitAnyならFALSE
130 @param[in] millisecondsTimeout タイムアウトまでの時間。-1 As DWordなら無限に待ち続ける。
131 @return シグナルが発生したらTrue、タイムアウトになったらFalse。
132 @date 2008/08/27
133 @auther Egtra
134 */
135 Static Function waitImpl(handles As Collections.Generic.IList<WaitHandle>, waitAll As BOOL, millisecondsTimeout As DWord) As Boolean
136' If ActiveBasic.IsNothing(handles) Then
137' Throw New ArgumentNullException("handles")
138' End If
139 Dim count = handles.Count
140 If count > MAXIMUM_WAIT_OBJECTS Then
141 Throw New InvalidOperationException("handles.Count > MAXIMUM_WAIT_OBJECTS")
142 End If
143 Return afterWait(WaitForMultipleObjects(count, ToArrayOfHANDLE(handles), waitAll, millisecondsTimeout), count)
144 End Function
145
146 /*!
147 @brief 待機が終了した後の処理を行う。
148 @param[in] ret 待機関数の戻り値
149 @param[in] n 待機させたハンドルの数
150 @return シグナルが発生したらTrue、タイムアウトになったらFalse。
151 @auther Egtra
152 */
153 Static Function afterWait(ret As DWord, n As DWord) As Boolean
154 Select Case ret
155 Case WAIT_TIMEOUT
156 Return False
157 Case WAIT_ABANDONED
158 Throw New AbandonedMutexException
159 Debug
160 ExitThread(0)
161 Case WAIT_FAILED
162 ActiveBasic.Windows.ThrowWithLastError()
163 Case Else
164 If WAIT_OBJECT_0 <= ret And ret < WAIT_OBJECT_0 + n Then
165 Return True
166 End If
167 ' ObjectDisposedException?
168 Debug
169 ExitThread(0)
170 End Select
171 End Function
172
173 /*!
174 @brief WaitHandleのリストをHANDLE配列にする。
175 @param[in] handles 変換元
176 @return 変換済みの配列の要素を指すポインタ
177 @date 2008/08/27
178 @auther Egtra
179 */
180 Static Function ToArrayOfHANDLE(handles As Collections.Generic.IList<WaitHandle>) As *HANDLE
181 Dim count = handles.Count
182 ToArrayOfHANDLE = GC_malloc(count * SizeOf(HANDLE))
183 Dim i As Long
184 For i = 0 To ELM(count)
185 ToArrayOfHANDLE[i] = handles.Item[i].h
186 Next
187 End Function
188
189 /*!
190 @brief Long値が0以上か-1でない場合、例外を投げる。
191 @param[in] x テストする値
192 @throw ArgumentOutOfRangeException -1未満の値のとき
193 @date 2008/08/27
194 @auther Egtra
195 */
196 Static Sub ThrowIfInvalidLongValue(x As Long)
197 If x < -1 Then
198 Throw New ArgumentOutOfRangeException("millisecondsTimeout")
199 End If
200 End Sub
201End Class
202
203End Namespace 'Threading
204End Namespace 'System
Note: See TracBrowser for help on using the repository browser.