source: trunk/Include/Classes/System/Threading/Thread.ab@ 493

Last change on this file since 493 was 493, checked in by NoWest, 16 years ago

IsAliveプロパティを追加

File size: 9.5 KB
Line 
1'Thread.ab
2
3'--------------------------------------------------------------------
4' スレッドの優先順位
5'--------------------------------------------------------------------
6Enum ThreadPriority
7 Highest = 2
8 AboveNormal = 1
9 Normal = 0
10 BelowNormal = -1
11 Lowest = -2
12End Enum
13
14TypeDef PTHREAD_START_ROUTINE = *Function(args As VoidPtr) As DWord
15
16
17'--------------------------------------------------------------------
18' スレッド クラス
19'--------------------------------------------------------------------
20Class Thread
21 m_hThread As HANDLE
22 m_dwThreadId As DWord
23 m_Priority As ThreadPriority
24
25 m_fp As PTHREAD_START_ROUTINE
26 m_args As VoidPtr
27 name As String
28
29 isThrowing As Boolean
30 throwingParamObject As Object
31
32 needFreeStructurePointers As *VoidPtr
33 countOfNeedFreeStructurePointers As Long
34
35Public
36 Sub Thread()
37 m_hThread=0
38 m_dwThreadId=0
39 m_Priority=ThreadPriority.Normal
40
41 m_fp=0
42
43 name = "sub thread"
44
45 isThrowing = False
46 throwingParamObject = Nothing
47 End Sub
48 Sub Thread(fp As PTHREAD_START_ROUTINE, args As VoidPtr)
49 m_hThread=0
50 m_dwThreadId=0
51 m_Priority=ThreadPriority.Normal
52
53 m_fp=fp
54 m_args=args
55
56 name = "sub thread"
57
58 isThrowing = False
59 throwingParamObject = Nothing
60 End Sub
61
62 Sub Thread(obj As Thread)
63 m_hThread=obj.m_hThread
64 m_dwThreadId=obj.m_dwThreadId
65 m_Priority=obj.m_Priority
66 m_fp=obj.m_fp
67 m_args=obj.m_args
68
69 name = "sub thread"
70
71 isThrowing = False
72 throwingParamObject = Nothing
73 End Sub
74
75 Sub Thread(hThread As HANDLE, dwThreadId As DWord, dummy As Long)
76 m_hThread=hThread
77 m_dwThreadId=dwThreadId
78
79 name = "sub thread"
80
81 isThrowing = False
82 throwingParamObject = Nothing
83 End Sub
84
85 Sub ~Thread()
86 End Sub
87
88
89 Function Equals(thread As Thread) As Boolean
90 Return m_dwThreadId = thread.m_dwThreadId
91 End Function
92
93 '-----------------------
94 ' Public Properties
95 '-----------------------
96 Function IsAlive() As Boolean
97 Dim code As DWord
98 GetExitCodeThread(m_hThread,code)
99 If code=STILL_ACTIVE Then
100 Return True
101 Else
102 Return False
103 End If
104 End Function
105
106 'Priority Property
107 Sub Priority(value As ThreadPriority)
108 m_Priority=value
109 SetThreadPriority(m_hThread,value)
110 End Sub
111 Function Priority() As ThreadPriority
112 Return m_Priority
113 End Function
114
115 'ThreadId
116 Function ThreadId() As DWord
117 Return m_dwThreadId
118 End Function
119
120 Function Name() As String
121 Return name
122 End Function
123 Sub Name( name As String )
124 This.name = name
125 End Sub
126
127 Sub Start()
128 Dim ThreadId As DWord
129 m_hThread=_beginthreadex(NULL,0,AddressOf(_run),VarPtr(This),CREATE_SUSPENDED,m_dwThreadId)
130 SetThreadPriority(m_hThread,m_Priority)
131 Resume()
132 End Sub
133
134Private
135 Function Cdecl _run() As Long
136 '------------
137 ' 前処理
138 '------------
139
140 ' 構造体の一時メモリ退避用領域を作成
141 needFreeStructurePointers = _System_malloc( 1 )
142 countOfNeedFreeStructurePointers = 0
143
144 'GCにスレッド開始を通知
145 _System_pobj_AllThreads->BeginThread(This, _System_GetSp() As *LONG_PTR)
146
147
148 '------------
149 '実行
150 '------------
151 _run=Run()
152
153
154 '------------
155 '後処理
156 '------------
157
158 'GCにスレッド終了を通知
159 _System_pobj_AllThreads->EndThread(This)
160
161 ' 構造体の一時メモリ退避用領域を破棄
162 _System_free( needFreeStructurePointers )
163
164 '自身のスレッドハンドルを閉じる
165 CloseHandle(InterlockedExchangePointer(VarPtr(m_hThread),NULL))
166 m_hThread=0
167
168 End Function
169
170Public
171 Virtual Function Run() As Long
172 If m_fp Then
173 Run=m_fp(m_args)
174 End If
175 End Function
176
177 Sub Suspend()
178 If SuspendThread(m_hThread) = &HFFFFFFFF Then
179 debug
180 End If
181 End Sub
182 Sub Resume()
183 If ResumeThread(m_hThread) = &HFFFFFFFF Then
184 debug
185 End If
186 End Sub
187
188 Function __GetContext(ByRef Context As CONTEXT) As BOOL
189 Return GetThreadContext(m_hThread,Context)
190 End Function
191 Function __SetContext(ByRef Context As CONTEXT) As BOOL
192 Return SetThreadContext(m_hThread,Context)
193 End Function
194
195 Sub __Throw( ex As Object )
196 isThrowing = True
197 throwingParamObject = ex
198 End Sub
199 Sub __Catched()
200 isThrowing = False
201 throwingParamObject = Nothing
202 End Sub
203 Function __IsThrowing() As Boolean
204 Return isThrowing
205 End Function
206 Function __GetThrowintParamObject() As Object
207 Return throwingParamObject
208 End Function
209
210 Sub __AddNeedFreeTempStructure( structurePointer As VoidPtr )
211 needFreeStructurePointers = _System_realloc( needFreeStructurePointers, ( countOfNeedFreeStructurePointers + 1 ) * SizeOf(VoidPtr) )
212 needFreeStructurePointers[countOfNeedFreeStructurePointers] = structurePointer
213 countOfNeedFreeStructurePointers ++
214 End Sub
215
216 Sub __FreeTempStructure()
217 Dim i = 0 As Long
218 While i<countOfNeedFreeStructurePointers
219 free( needFreeStructurePointers[i] )
220 i++
221 Wend
222 countOfNeedFreeStructurePointers = 0
223 End Sub
224
225
226 Static Function CurrentThread() As Thread
227 Return _System_pobj_AllThreads->CurrentThread()
228 End Function
229End Class
230
231Dim _System_pobj_AllThreads As *Detail._System_CThreadCollection
232
233Namespace Detail
234
235'--------------------------------------------------------------------
236' すべてのスレッドの管理
237'--------------------------------------------------------------------
238' TODO: このクラスをシングルトンにする
239
240Class _System_CThreadCollection
241Public
242 collection As *ThreadInfo
243 ThreadNum As Long
244
245 CriticalSection As CRITICAL_SECTION
246
247 Sub _System_CThreadCollection()
248 collection = GC_malloc(1)
249 ThreadNum = 0
250 InitializeCriticalSection(CriticalSection)
251 End Sub
252
253 Sub ~_System_CThreadCollection()
254 Dim i As Long
255 For i=0 To ELM(ThreadNum)
256 With collection[i]
257 If .thread Then
258 .thread = Nothing
259 .stackBase = 0
260 .exception = Nothing
261 End If
262 End With
263 Next
264 collection = 0
265 DeleteCriticalSection(CriticalSection)
266 End Sub
267
268 'スレッドを生成
269 Sub BeginThread(thread As Thread, NowSp As *LONG_PTR)
270 EnterCriticalSection(CriticalSection)
271 Dim i = FindFreeIndex
272 With collection[i]
273 .thread = thread
274 .stackBase = NowSp
275 .exception = New ExceptionService '例外処理管理用オブジェクトを生成
276 End With
277 LeaveCriticalSection(CriticalSection)
278 End Sub
279Private
280 'クリティカルセション内で呼ぶこと
281 Function FindFreeIndex() As Long
282 Dim i As Long
283 For i = 0 To ELM(ThreadNum)
284 If ActiveBasic.IsNothing(collection[i].thread) Then
285 FindFreeIndex = i
286 Exit Function
287 End If
288 Next
289 ThreadNum++
290 collection = realloc(collection, ThreadNum * SizeOf(ThreadInfo))
291 FindFreeIndex = i
292 End Function
293Public
294
295 'スレッドを終了
296 Sub EndThread(thread As Thread)
297 EnterCriticalSection(CriticalSection)
298 Dim i As Long
299 For i = 0 To ELM(ThreadNum)
300 With collection[i]
301 If thread.Equals(.thread) Then
302 .thread = Nothing
303 .stackBase = 0
304 .exception = Nothing
305 Exit For
306 End If
307 End With
308 Next
309 LeaveCriticalSection(CriticalSection)
310 End Sub
311
312 ' すべてのスレッドを中断
313 Sub SuspendAllThread()
314 Dim i As Long
315 For i = 0 To ELM(ThreadNum)
316 With collection[i]
317 If Not ActiveBasic.IsNothing(.thread) Then
318 .thread.Suspend()
319 End If
320 End With
321 Next
322 End Sub
323
324 ' すべてのスレッドを再開
325 Sub ResumeAllThread()
326 Dim i As Long
327 For i = 0 To ELM(ThreadNum)
328 With collection[i]
329 If Not ActiveBasic.IsNothing(.thread) Then
330 .thread.Resume()
331 End If
332 End With
333 Next
334 End Sub
335/*
336 ' 自分以外のスレッドを中断
337 Sub SuspendAnotherThread()
338 Dim currentThread = CurrentThread()
339
340 Dim i As Long
341 For i=0 To ELM(ThreadNum)
342 With collection[i]
343 If currentThread.Equals(.thread) Then
344 Continue
345 ElseIf Not ActiveBasic.IsNothing(.thread) Then
346 .thread.Suspend()
347 End If
348 End With
349 Next
350 End Sub
351
352 ' 自分以外のスレッドを再開
353 Sub ResumeAnotherThread()
354 Dim currentThread = CurrentThread()
355
356 Dim i As Long
357 For i=0 To ELM(ThreadNum)
358 With collection[i]
359 If currentThread.Equals(.thread) Then
360 Continue
361 ElseIf Not ActiveBasic.IsNothing(.thread) Then
362 .thread.Resume()
363 End If
364 End With
365 Next
366 End Sub
367*/
368 'カレントスレッドを取得
369 Function CurrentThread() As Thread
370 Dim p = CurrentThreadInfo()
371 If p = 0 Then
372 ' TODO: エラー処理
373 OutputDebugString( Ex"カレントスレッドの取得に失敗\r\n" )
374 debug
375 Exit Function
376 End If
377 CurrentThread = p->thread
378 End Function
379
380 Function CurrentThreadInfo() As *ThreadInfo
381 CurrentThreadInfo = FindThreadInfo(GetCurrentThreadId())
382 End Function
383
384 Function FindThreadInfo(threadID As DWord) As *ThreadInfo
385 Dim i As Long
386 For i = 0 To ELM(ThreadNum)
387 If collection[i].thread.ThreadId = threadID Then
388 FindThreadInfo = VarPtr(collection[i])
389 Exit Function
390 End If
391 Next
392 End Function
393
394Private
395 '------------------------------------------
396 ' スレッド固有の例外処理制御
397 '------------------------------------------
398
399Public
400 Function GetCurrentException() As ExceptionService
401 Dim dwNowThreadId = GetCurrentThreadId()
402
403 Dim i As Long
404 For i=0 To ELM(ThreadNum)
405 With collection[i]
406 If .thread.ThreadId = dwNowThreadId Then
407 Return .exception
408 End If
409 End With
410 Next
411
412 OutputDebugString( Ex"カレントスレッドの取得に失敗\r\n" )
413 Return Nothing
414 End Function
415End Class
416
417Type ThreadInfo
418 thread As Thread
419 stackBase As *LONG_PTR
420 exception As ExceptionService
421End Type
422
423End Namespace 'Detail
424
425Sub _System_AddNeedFreeTempStructure( structurePointer As VoidPtr )
426 Thread.CurrentThread.__AddNeedFreeTempStructure( structurePointer )
427End Sub
428Sub _System_FreeTempStructure()
429 Thread.CurrentThread.__FreeTempStructure()
430End Sub
Note: See TracBrowser for help on using the repository browser.