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