source: trunk/ab5.0/ablib/src/Classes/System/Threading/Thread.ab@ 536

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

細かい修正。
Str$にStringを受け取る多重定義を追加した。
複数libを作るバッチで、コンパイルエラーが発生したら以後のビルドを行わないようにした。
Threadクラスの_beginthreadexをCreateThreadへ変更した。
ole2.abを全体が使える古い版へ戻した。
SendMessageCallback/SendMessageTimeoutを追加した。
GCHandleで登録が解除されない状態が起こる問題を直した。

File size: 11.5 KB
Line 
1'Thread.ab
2
3NameSpace System
4
5/*タイプ*/
6TypeDef LocalDataStoreSlot = Long
7
8
9NameSpace Threading
10
11/*列挙体*/
12Enum ThreadPriority
13 Highest = 2
14 AboveNormal = 1
15 Normal = 0
16 BelowNormal = -1
17 Lowest = -2
18End Enum
19
20Enum ThreadState
21 'スレッド状態に AbortRequested が含まれ、そのスレッドは停止していますが、状態はまだ Stopped に変わっていません。
22 Aborted
23 'スレッド上で Thread.Abort メソッドを呼び出しますが、そのスレッドの終了を試みる保留中の System.Threading.ThreadAbortException をスレッドが受け取っていません。
24 AbortRequested
25 'スレッドは、フォアグラウンド スレッドではなく、バックグランド スレッドとして実行します。この状態は、Thread.IsBackground プロパティを設定して制御されます。
26 Background
27 'スレッドをブロックせずに起動します。保留中の ThreadAbortException もありません。
28 Running
29 'スレッドを停止します。
30 Stopped
31 'スレッドの停止を要求します。これは、内部でだけ使用します。
32 StopRequested
33 'スレッドを中断します。
34 Suspended
35 'スレッドの中断を要求します。
36 SuspendRequested
37 'スレッド上に Thread.Start メソッドを呼び出しません。
38 Unstarted
39 'スレッドがブロックされています。これは、Thread.Sleep または Thread.Join の呼び出し、ロックの要求 (たとえば、Monitor.Enter や Monitor.Wait の呼び出しによる)、または ManualResetEvent などのスレッド同期オブジェクトの待機の結果である可能性があります。
40 WaitSleepJoin
41End Enum
42
43/*
44デリゲート
45*/
46Delegate Sub ThreadStart()
47
48
49/*
50関数ポインタ
51*/
52TypeDef PTHREAD_START_ROUTINE = *Function(args As VoidPtr) As DWord
53
54
55/*
56クラス
57*/
58Class Thread
59 m_hThread As HANDLE
60 m_dwThreadId As DWord
61 m_Priority As ThreadPriority
62
63 m_fp As PTHREAD_START_ROUTINE
64 m_dg As ThreadStart
65 m_args As VoidPtr
66 name As String
67 state As ThreadState
68
69 isThrowing As Boolean
70 throwingParamObject As Object
71
72 needFreeStructurePointers As *VoidPtr
73 countOfNeedFreeStructurePointers As Long
74
75Public
76 Sub Thread()
77 m_hThread=0
78 m_dwThreadId=0
79 m_Priority=ThreadPriority.Normal
80
81 m_fp=0
82
83 name = "sub thread"
84 state = ThreadState.Unstarted
85
86 isThrowing = False
87 throwingParamObject = Nothing
88 End Sub
89 Sub Thread(fp As PTHREAD_START_ROUTINE, args As VoidPtr)
90 m_hThread=0
91 m_dwThreadId=0
92 m_Priority=ThreadPriority.Normal
93
94 m_fp=fp
95 m_args=args
96
97 name = "sub thread"
98 state = ThreadState.Unstarted
99
100 isThrowing = False
101 throwingParamObject = Nothing
102 End Sub
103
104 Sub Thread(obj As Thread)
105 m_hThread=obj.m_hThread
106 m_dwThreadId=obj.m_dwThreadId
107 m_Priority=obj.m_Priority
108 m_fp=obj.m_fp
109 m_args=obj.m_args
110
111 name = "sub thread"
112 state = ThreadState.Unstarted
113
114 isThrowing = False
115 throwingParamObject = Nothing
116 End Sub
117
118 Sub Thread(hThread As HANDLE, dwThreadId As DWord, dummy As Long)
119 m_hThread=hThread
120 m_dwThreadId=dwThreadId
121
122 name = "sub thread"
123 state = ThreadState.Unstarted
124
125 isThrowing = False
126 throwingParamObject = Nothing
127 End Sub
128
129 Sub ~Thread()
130 End Sub
131
132 Function Equals(thread As Thread) As Boolean
133 Return m_dwThreadId = thread.m_dwThreadId
134 End Function
135
136Public 'public property
137 Function IsAlive() As Boolean
138 Dim code As DWord
139 GetExitCodeThread(m_hThread,code)
140 If code=STILL_ACTIVE Then
141 Return True
142 Else
143 Return False
144 End If
145 End Function
146
147 'Priority Property
148 Sub Priority(value As ThreadPriority)
149 m_Priority=value
150 SetThreadPriority(m_hThread,value)
151 End Sub
152 Function Priority() As ThreadPriority
153 Return m_Priority
154 End Function
155
156 'ThreadId
157 Function ThreadId() As DWord
158 Return m_dwThreadId
159 End Function
160
161 Function ThreadState() As System.Threading.ThreadState
162 Return This.state
163 End Function
164
165 Function Name() As String
166 Return name
167 End Function
168 Sub Name( name As String )
169 This.name = name
170 End Sub
171
172Public 'public method
173/* Sub Abort()
174 TODO '実装のためにはかなり検討が必要
175 'This.__Throw(New ThreadAbortException)
176 End Sub*/
177
178 Sub Start()
179 Dim pfn = AddressOf(_run) As LONG_PTR
180 m_hThread=CreateThread(NULL,0,pfn As LPTHREAD_START_ROUTINE,VarPtr(This),CREATE_SUSPENDED,m_dwThreadId)
181 SetThreadPriority(m_hThread,m_Priority)
182 This.Resume()
183 End Sub
184
185 Virtual Function Run() As Long
186 If m_fp Then
187 Run=m_fp(m_args)
188 End If
189 End Function
190
191 Sub Suspend()
192 This.state = ThreadState.SuspendRequested
193 If SuspendThread(m_hThread) = &HFFFFFFFF Then
194 This.state = ThreadState.Unstarted
195 Debug 'Throw New ThreadStateException
196 End If
197 This.state = ThreadState.Suspended
198 End Sub
199 Sub Resume()
200 If ResumeThread(m_hThread) = &HFFFFFFFF Then
201 state = ThreadState.Unstarted
202 Debug 'Throw New ThreadStateException
203 End If
204 This.state = ThreadState.Running
205 End Sub
206
207/* Function GetData(LocalDataStoreSlot)
208 End Function
209 Sub SetData(LocalDataStoreSlot)
210 End Sub*/
211
212 Static Function CurrentThread() As Thread
213 Return _System_pobj_AllThreads->CurrentThread()
214 End Function
215
216 /*------------------------ クラス内部用 --------------------------*/
217Private
218 Function _run() As Long
219 '------------
220 ' 前処理
221 '------------
222
223 ' 構造体の一時メモリ退避用領域を作成
224 needFreeStructurePointers = _System_malloc( 1 )
225 countOfNeedFreeStructurePointers = 0
226
227 'GCにスレッド開始を通知
228 _System_pobj_AllThreads->BeginThread(This, _System_GetSp() As *LONG_PTR)
229
230
231 '------------
232 '実行
233 '------------
234 _run=Run()
235
236
237 '------------
238 '後処理
239 '------------
240
241 'GCにスレッド終了を通知
242 _System_pobj_AllThreads->EndThread(This)
243
244 ' 構造体の一時メモリ退避用領域を破棄
245 _System_free( needFreeStructurePointers )
246
247 '自身のスレッドハンドルを閉じる
248 CloseHandle(InterlockedExchangePointer(VarPtr(m_hThread),NULL))
249 m_hThread=0
250
251 End Function
252
253 /*------------------------ システム用 --------------------------*/
254Public
255 Function __GetContext(ByRef Context As CONTEXT) As BOOL
256 Return GetThreadContext(m_hThread,Context)
257 End Function
258 Function __SetContext(ByRef Context As CONTEXT) As BOOL
259 Return SetThreadContext(m_hThread,Context)
260 End Function
261
262 Sub __Throw( ex As Object )
263 isThrowing = True
264 throwingParamObject = ex
265 End Sub
266 Sub __Catched()
267 isThrowing = False
268 throwingParamObject = Nothing
269 End Sub
270 Function __IsThrowing() As Boolean
271 Return isThrowing
272 End Function
273 Function __GetThrowintParamObject() As Object
274 Return throwingParamObject
275 End Function
276
277 Sub __AddNeedFreeTempStructure( structurePointer As VoidPtr )
278 needFreeStructurePointers = _System_realloc( needFreeStructurePointers, ( countOfNeedFreeStructurePointers + 1 ) * SizeOf(VoidPtr) )
279 needFreeStructurePointers[countOfNeedFreeStructurePointers] = structurePointer
280 countOfNeedFreeStructurePointers ++
281 End Sub
282
283 Sub __FreeTempStructure()
284 Dim i = 0 As Long
285 While i<countOfNeedFreeStructurePointers
286 free( needFreeStructurePointers[i] )
287 i++
288 Wend
289 countOfNeedFreeStructurePointers = 0
290 End Sub
291End Class
292
293
294Namespace Detail
295
296'--------------------------------------------------------------------
297' すべてのスレッドの管理
298'--------------------------------------------------------------------
299' TODO: このクラスをシングルトンにする
300
301Class _System_CThreadCollection
302Public
303 collection As *ThreadInfo
304 ThreadNum As Long
305
306 CriticalSection As CRITICAL_SECTION
307
308 Sub _System_CThreadCollection()
309 collection = GC_malloc(1)
310 ThreadNum = 0
311 InitializeCriticalSection(CriticalSection)
312 End Sub
313
314 Sub ~_System_CThreadCollection()
315 Dim i As Long
316 For i=0 To ELM(ThreadNum)
317 With collection[i]
318 If ActiveBasic.IsNothing( .thread ) Then
319 .thread = Nothing
320 .stackBase = 0
321 .exception = Nothing
322 End If
323 End With
324 Next
325 collection = 0
326 DeleteCriticalSection(CriticalSection)
327 End Sub
328
329 'スレッドを生成
330 Sub BeginThread(thread As Thread, NowSp As *LONG_PTR)
331 EnterCriticalSection(CriticalSection)
332 Dim i = FindFreeIndex
333 With collection[i]
334 .thread = thread
335 .stackBase = NowSp
336 .exception = New ExceptionService '例外処理管理用オブジェクトを生成
337 End With
338 LeaveCriticalSection(CriticalSection)
339 End Sub
340Private
341 'クリティカルセション内で呼ぶこと
342 Function FindFreeIndex() As Long
343 Dim i As Long
344 For i = 0 To ELM(ThreadNum)
345 If ActiveBasic.IsNothing(collection[i].thread) Then
346 FindFreeIndex = i
347 Exit Function
348 End If
349 Next
350 ThreadNum++
351 collection = realloc(collection, ThreadNum * SizeOf(ThreadInfo))
352 FindFreeIndex = i
353 End Function
354Public
355
356 'スレッドを終了
357 Sub EndThread(thread As Thread)
358 EnterCriticalSection(CriticalSection)
359 Dim i As Long
360 For i = 0 To ELM(ThreadNum)
361 With collection[i]
362 If thread.Equals(.thread) Then
363 .thread = Nothing
364 .stackBase = 0
365 .exception = Nothing
366 Exit For
367 End If
368 End With
369 Next
370 LeaveCriticalSection(CriticalSection)
371 End Sub
372
373 ' すべてのスレッドを中断
374 Sub SuspendAllThread()
375 Dim i As Long
376 For i = 0 To ELM(ThreadNum)
377 With collection[i]
378 If Not ActiveBasic.IsNothing(.thread) Then
379 .thread.Suspend()
380 End If
381 End With
382 Next
383 End Sub
384
385 ' すべてのスレッドを再開
386 Sub ResumeAllThread()
387 Dim i As Long
388 For i = 0 To ELM(ThreadNum)
389 With collection[i]
390 If Not ActiveBasic.IsNothing(.thread) Then
391 .thread.Resume()
392 End If
393 End With
394 Next
395 End Sub
396/*
397 ' 自分以外のスレッドを中断
398 Sub SuspendAnotherThread()
399 Dim currentThread = CurrentThread()
400
401 Dim i As Long
402 For i=0 To ELM(ThreadNum)
403 With collection[i]
404 If currentThread.Equals(.thread) Then
405 Continue
406 ElseIf Not ActiveBasic.IsNothing(.thread) Then
407 .thread.Suspend()
408 End If
409 End With
410 Next
411 End Sub
412
413 ' 自分以外のスレッドを再開
414 Sub ResumeAnotherThread()
415 Dim currentThread = CurrentThread()
416
417 Dim i As Long
418 For i=0 To ELM(ThreadNum)
419 With collection[i]
420 If currentThread.Equals(.thread) Then
421 Continue
422 ElseIf Not ActiveBasic.IsNothing(.thread) Then
423 .thread.Resume()
424 End If
425 End With
426 Next
427 End Sub
428*/
429 'カレントスレッドを取得
430 Function CurrentThread() As Thread
431 Dim p = CurrentThreadInfo()
432 If p = 0 Then
433 ' TODO: エラー処理
434 OutputDebugString( Ex"カレントスレッドの取得に失敗\r\n" )
435 debug
436 Exit Function
437 End If
438 CurrentThread = p->thread
439 End Function
440
441 Function CurrentThreadInfo() As *ThreadInfo
442 CurrentThreadInfo = FindThreadInfo(GetCurrentThreadId())
443 End Function
444
445 Function FindThreadInfo(threadID As DWord) As *ThreadInfo
446 Dim i As Long
447 For i = 0 To ELM(ThreadNum)
448 If collection[i].thread.ThreadId = threadID Then
449 FindThreadInfo = VarPtr(collection[i])
450 Exit Function
451 End If
452 Next
453 End Function
454
455Private
456 '------------------------------------------
457 ' スレッド固有の例外処理制御
458 '------------------------------------------
459
460Public
461 Function GetCurrentException() As ExceptionService
462 Dim dwNowThreadId = GetCurrentThreadId()
463
464 Dim i As Long
465 For i=0 To ELM(ThreadNum)
466 With collection[i]
467 If .thread.ThreadId = dwNowThreadId Then
468 Return .exception
469 End If
470 End With
471 Next
472
473 OutputDebugString( Ex"カレントスレッドの取得に失敗\r\n" )
474 Return Nothing
475 End Function
476End Class
477
478Type ThreadInfo
479 thread As Thread
480 stackBase As *LONG_PTR
481 exception As ExceptionService
482End Type
483
484End Namespace 'Detail
485End NameSpace 'Threading
486End NameSpace 'System
487
488
489/* システムが使う変数 */
490Dim _System_pobj_AllThreads As *System.Threading.Detail._System_CThreadCollection
491
492/* システムが呼び出す関数 */
493Sub _System_AddNeedFreeTempStructure( structurePointer As VoidPtr )
494 System.Threading.Thread.CurrentThread.__AddNeedFreeTempStructure( structurePointer )
495End Sub
496Sub _System_FreeTempStructure()
497 System.Threading.Thread.CurrentThread.__FreeTempStructure()
498End Sub
Note: See TracBrowser for help on using the repository browser.