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
RevLine 
[46]1' Classes/System/Threading/WaitHandle.ab
2
[261]3Namespace System
4Namespace Threading
5
[258]6Namespace Detail
7 TypeDef PFNSignalObjectAndWait = *Function(hObjectToSignal As HANDLE, hObjectToWaitOn As HANDLE, dwMilliseconds As DWord, bAlertable As DWord) As DWord
8End Namespace
9
[46]10Class WaitHandle
[381]11 Implements System.IDisposable
[46]12Public
[77]13 ' Properties
14' Const Function SafeWaitHandle() As SafeWaitHandle
15' Sub SafeWaitHandle(h As SafeWaitHandle)
[46]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
[77]25 ' Methods
[599]26 Sub WaitHandle()
[408]27 End Sub
[77]28
29 Virtual Sub ~WaitHandle()
[408]30 This.Dispose()
[77]31 End Sub
32
[46]33 Virtual Sub Close()
[408]34 This.Dispose()
[46]35 End Sub
36
[388]37 Virtual Sub Dispose()
[261]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
[599]45 Return WaitOne(INFINITE As DWord)
[47]46 End Function
[46]47
[599]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)
[47]53 End Function
[46]54
[599]55 Function WaitOne(millisecondsTimeout As Long) As Boolean
56 ThrowIfInvalidLongValue(millisecondsTimeout)
57 Return WaitOne(millisecondsTimeout As DWord)
[408]58 End Function
59
[599]60 Function WaitOne(timeout As System.TimeSpan) As Boolean
61 Return WaitOne(timeout.TotalMilliseconds() As Long)
[47]62 End Function
[46]63
[599]64 Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>) As Boolean
65 Return waitImpl(handles, TRUE, INFINITE As DWord)
[47]66 End Function
[46]67
[599]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)
[408]71 End Function
[46]72
[599]73 Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As DWord) As Boolean
74 Return waitImpl(handles, TRUE, millisecondsTimeout)
[47]75 End Function
[46]76
[599]77 Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, timeout As System.TimeSpan) As Boolean
78 Return WaitAny(handles, timeout.TotalMilliseconds() As Long)
[47]79 End Function
[46]80
[599]81 Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>) As Boolean
82 Return waitImpl(handles, FALSE, INFINITE As DWord)
[408]83 End Function
84
[599]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
[261]98 Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle) As Boolean
[599]99 Return SignalAndWait(toSignal, toWaitOn, INFINITE)
[47]100 End Function
[46]101
[599]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)
[408]104 End Function
105
[599]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
[581]111 Dim pSignalObjectAndWait = GetProcAddress(GetModuleHandle("Kernel32.dll"), ToMBStr("SignalObjectAndWait")) As Detail.PFNSignalObjectAndWait
[46]112 If pSignalObjectAndWait = 0 Then
[388]113 Throw New PlatformNotSupportedException("WaitHandle.SignalAndWait: This platform doesn't supoort this operation.")
[46]114 End If
[599]115 Return afterWait(pSignalObjectAndWait(toSignal.Handle, toWaitOn.Handle, millisecondsTimeout As DWord, FALSE), 1)
[47]116 End Function
[46]117
[599]118 Static Const WaitTimeout = WAIT_TIMEOUT
[46]119
120Protected
121 Static Const InvalidHandle = INVALID_HANDLE_VALUE As HANDLE
122
123Private
124 h As HANDLE
125
[599]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
[46]154 Select Case ret
155 Case WAIT_TIMEOUT
[261]156 Return False
[46]157 Case WAIT_ABANDONED
[599]158 Throw New AbandonedMutexException
[46]159 Debug
160 ExitThread(0)
[599]161 Case WAIT_FAILED
162 ActiveBasic.Windows.ThrowWithLastError()
[46]163 Case Else
[47]164 If WAIT_OBJECT_0 <= ret And ret < WAIT_OBJECT_0 + n Then
[261]165 Return True
[47]166 End If
[46]167 ' ObjectDisposedException?
168 Debug
169 ExitThread(0)
170 End Select
[58]171 End Function
[599]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
[46]201End Class
202
[261]203End Namespace 'Threading
204End Namespace 'System
Note: See TracBrowser for help on using the repository browser.