source: Include/Classes/System/Threading/Thread.ab@ 220

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

Namespaceステートメントを実装した。
3番目に確保されるメモリオブジェクトが解放されないバグを修正。

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