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

Last change on this file since 330 was 330, checked in by dai, 17 years ago

コンストラクタパラメータを処理中にGCがかかると、初期化中オブジェクトのスキャンで強制終了してしまうバグを修正。
グローバル領域に保持されるオブジェクトの一部がGCによって不正に回収されてしまうバグを修正。
Thread.Nameプロパティを実装

File size: 7.7 KB
Line 
1'threading.sbp
2
3
4'--------------------------------------------------------------------
5' スレッドの優先順位
6'--------------------------------------------------------------------
7Enum ThreadPriority
8 Highest = 2
9 AboveNormal = 1
10 Normal = 0
11 BelowNormal = -1
12 Lowest = -2
13End Enum
14
15TypeDef PTHREAD_START_ROUTINE = *Function(args As VoidPtr) As DWord
16
17
18'--------------------------------------------------------------------
19' スレッド クラス
20'--------------------------------------------------------------------
21Class Thread
22 m_hThread As HANDLE
23 m_dwThreadId As DWord
24 m_Priority As ThreadPriority
25
26 m_fp As PTHREAD_START_ROUTINE
27 m_args As VoidPtr
28 name As String
29
30Public
31 Sub Thread()
32 m_hThread=0
33 m_dwThreadId=0
34 m_Priority=ThreadPriority.Normal
35
36 m_fp=0
37
38 name = "sub thread"
39 End Sub
40 Sub Thread(fp As PTHREAD_START_ROUTINE, args As VoidPtr)
41 m_hThread=0
42 m_dwThreadId=0
43 m_Priority=ThreadPriority.Normal
44
45 m_fp=fp
46 m_args=args
47
48 name = "sub thread"
49 End Sub
50
51 Sub Thread(obj As Thread)
52 m_hThread=obj.m_hThread
53 m_dwThreadId=obj.m_dwThreadId
54 m_Priority=obj.m_Priority
55 m_fp=obj.m_fp
56 m_args=obj.m_args
57
58 name = "sub thread"
59 End Sub
60
61 Sub Thread(hThread As HANDLE, dwThreadId As DWord, dummy As Long)
62 m_hThread=hThread
63 m_dwThreadId=dwThreadId
64
65 name = "sub thread"
66 End Sub
67
68 Sub ~Thread()
69 End Sub
70
71
72 Function Equals(thread As Thread) As Boolean
73 Return m_dwThreadId = thread.m_dwThreadId
74 End Function
75
76 '-----------------------
77 ' Public Properties
78 '-----------------------
79
80
81 'Priority Property
82 Sub Priority(value As ThreadPriority)
83 m_Priority=value
84 SetThreadPriority(m_hThread,value)
85 End Sub
86 Function Priority() As ThreadPriority
87 Return m_Priority
88 End Function
89
90 'ThreadId
91 Function ThreadId() As DWord
92 Return m_dwThreadId
93 End Function
94
95 Function Name() As String
96 Return name
97 End Function
98 Sub Name( name As String )
99 This.name = name
100 End Sub
101
102
103
104
105
106 Sub Start()
107 Dim ThreadId As DWord
108 m_hThread=_beginthreadex(NULL,0,AddressOf(_run),VarPtr(This),CREATE_SUSPENDED,m_dwThreadId)
109 SetThreadPriority(m_hThread,m_Priority)
110 Resume()
111 End Sub
112
113Private
114 Function Cdecl _run() As Long
115 '------------
116 ' 前処理
117 '------------
118
119 'GCにスレッド開始を通知
120 _System_pobj_AllThreads->BeginThread(VarPtr(This),_System_GetSp() As *LONG_PTR)
121
122
123 '------------
124 '実行
125 '------------
126 _run=Run()
127
128
129 '------------
130 '後処理
131 '------------
132
133 'GCにスレッド終了を通知
134 _System_pobj_AllThreads->EndThread(VarPtr(This))
135
136 '自身のスレッドハンドルを閉じる
137 CloseHandle(m_hThread)
138 m_hThread=0
139
140 End Function
141
142Public
143 Virtual Function Run() As Long
144 If m_fp Then
145 Run=m_fp(m_args)
146 End If
147 End Function
148
149 Sub Suspend()
150 If SuspendThread(m_hThread) = &HFFFFFFFF Then
151 debug
152 End If
153 End Sub
154 Sub Resume()
155 If ResumeThread(m_hThread) = &HFFFFFFFF Then
156 debug
157 End If
158 End Sub
159
160 Function __GetContext(ByRef Context As CONTEXT) As BOOL
161 Return GetThreadContext(m_hThread,Context)
162 End Function
163 Function __SetContext(ByRef Context As CONTEXT) As BOOL
164 Return SetThreadContext(m_hThread,Context)
165 End Function
166
167
168 Static Function CurrentThread() As Thread
169 Return _System_pobj_AllThreads->CurrentThread()
170 End Function
171End Class
172
173
174'--------------------------------------------------------------------
175' すべてのスレッドの管理
176'--------------------------------------------------------------------
177' TODO: このクラスをシングルトンにする
178Class _System_CThreadCollection
179Public
180 ppobj_Thread As **Thread
181 pStackBase As **LONG_PTR
182 ThreadNum As Long
183
184 CriticalSection As CRITICAL_SECTION
185
186 Sub _System_CThreadCollection()
187 ppobj_Thread=GC_malloc(1)
188 pStackBase=HeapAlloc(_System_hProcessHeap,0,1)
189 ppException=HeapAlloc(_System_hProcessHeap,0,1)
190 ThreadNum=0
191
192 'クリティカルセッションを生成
193 InitializeCriticalSection(CriticalSection)
194 End Sub
195
196 Sub ~_System_CThreadCollection()
197 Dim i As Long
198 For i=0 To ELM(ThreadNum)
199 If ppobj_Thread[i] Then
200 If i = 0 Then
201 Delete ppobj_Thread[i]
202 End If
203 ppobj_Thread[i]=0
204 pStackBase[i]=0
205 Delete ppException[i]
206 ppException[i]=0
207 Exit For
208 End If
209 Next
210
211 HeapFree(_System_hProcessHeap,0,pStackBase)
212 pStackBase=0
213
214 HeapFree(_System_hProcessHeap,0,ppException)
215 ppException = 0
216
217 ThreadNum=0
218
219 'クリティカルセッションを破棄
220 DeleteCriticalSection(CriticalSection)
221 End Sub
222
223 'スレッドを生成
224 Sub BeginThread(pThread As *Thread,NowSp As *LONG_PTR)
225 EnterCriticalSection(CriticalSection)
226
227 '例外処理管理用オブジェクトを生成
228 Dim pException As *ExceptionService
229 pException = New ExceptionService
230
231 Dim i As Long
232 For i=0 To ELM(ThreadNum)
233 If ppobj_Thread[i] = 0 Then
234 ppobj_Thread[i] = pThread
235 pStackBase[i] = NowSp
236 ppException[i] = pException
237 Exit For
238 End If
239 Next
240
241 If i = ThreadNum Then
242 ppobj_Thread=realloc(ppobj_Thread,(ThreadNum+1)*SizeOf(*Thread))
243 ppobj_Thread[ThreadNum]=pThread
244 pStackBase=HeapReAlloc(_System_hProcessHeap,0,pStackBase,(ThreadNum+1)*SizeOf(LONG_PTR))
245 pStackBase[ThreadNum]=NowSp
246 ppException=HeapReAlloc(_System_hProcessHeap,0,ppException,(ThreadNum+1)*SizeOf(*ExceptionService))
247 ppException[ThreadNum]=pException
248 ThreadNum++
249 End If
250 LeaveCriticalSection(CriticalSection)
251 End Sub
252
253 'スレッドを終了
254 Sub EndThread(pThread As *Thread)
255 EnterCriticalSection(CriticalSection)
256 Dim i As Long
257 For i=0 To ELM(ThreadNum)
258 If ppobj_Thread[i] = pThread Then
259 If i = 0 Then
260 Delete pThread
261 End If
262 ppobj_Thread[i]=0
263 pStackBase[i]=0
264 Delete ppException[i]
265 ppException[i]=0
266 Exit For
267 End If
268 Next
269 LeaveCriticalSection(CriticalSection)
270 End Sub
271
272 ' すべてのスレッドを中断
273 Sub SuspendAllThread()
274 Dim i As Long
275 For i=0 To ELM(ThreadNum)
276 If ppobj_Thread[i] Then
277 ppobj_Thread[i]->Suspend()
278 End If
279 Next
280 End Sub
281
282 ' すべてのスレッドを再開
283 Sub ResumeAllThread()
284 Dim i As Long
285 For i=0 To ELM(ThreadNum)
286 If ppobj_Thread[i] Then
287 ppobj_Thread[i]->Resume()
288 End If
289 Next
290 End Sub
291
292 ' 自分以外のスレッドを中断
293 Sub SuspendAnotherThread()
294 Dim currentThread = Thread.CurrentThread()
295
296 Dim i As Long
297 For i=0 To ELM(ThreadNum)
298
299 If currentThread.Equals( ppobj_Thread[i] As Object ) Then
300 Continue
301 End If
302
303 If ppobj_Thread[i] Then
304 ppobj_Thread[i]->Suspend()
305 End If
306 Next
307 End Sub
308
309 ' 自分以外のスレッドを再開
310 Sub ResumeAnotherThread()
311 Dim currentThread = Thread.CurrentThread()
312
313 Dim i As Long
314 For i=0 To ELM(ThreadNum)
315
316 If currentThread.Equals( ppobj_Thread[i] As Object ) Then
317 Continue
318 End If
319
320 If ppobj_Thread[i] Then
321 ppobj_Thread[i]->Resume()
322 End If
323 Next
324 End Sub
325
326 'カレントスレッドを取得
327 Function CurrentThread() As Thread
328 Dim dwNowThreadId As DWord
329 dwNowThreadId=GetCurrentThreadId()
330
331 Dim i As Long
332 For i=0 To ELM(ThreadNum)
333 If ppobj_Thread[i]->ThreadId=dwNowThreadId Then
334 Return ByVal ppobj_Thread[i]
335 End If
336 Next
337
338 ' TODO: エラー処理
339 OutputDebugString( "カレントスレッドの取得に失敗" )
340 debug
341 End Function
342
343
344Private
345 '------------------------------------------
346 ' スレッド固有の例外処理制御
347 '------------------------------------------
348 ppException As **ExceptionService
349
350Public
351 Function GetCurrentException() As *ExceptionService
352 Dim dwNowThreadId As DWord
353 dwNowThreadId=GetCurrentThreadId()
354
355 Dim i As Long
356 For i=0 To ELM(ThreadNum)
357 If ppobj_Thread[i]->ThreadId=dwNowThreadId Then
358 Return ppException[i]
359 End If
360 Next
361
362 Return NULL
363 End Function
364End Class
365Dim _System_pobj_AllThreads As *_System_CThreadCollection
Note: See TracBrowser for help on using the repository browser.