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

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

スレッド管理クラスで起きているメモリリークを解消

File size: 7.5 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( thread As Thread ) As Boolean
64 If m_dwThreadId = thread.m_dwThreadId Then
65 Return True
66 End If
67 Return 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 Dim i As Long
187 For i=0 To ELM(ThreadNum)
188 If ppobj_Thread[i] Then
189 If i = 0 Then
190 Delete ppobj_Thread[i]
191 End If
192 ppobj_Thread[i]=0
193 pStackBase[i]=0
194 Delete ppException[i]
195 ppException[i]=0
196 Exit For
197 End If
198 Next
199
200 HeapFree(_System_hProcessHeap,0,pStackBase)
201 pStackBase=0
202
203 HeapFree(_System_hProcessHeap,0,ppException)
204 ppException = 0
205
206 ThreadNum=0
207
208 'クリティカルセッションを破棄
209 DeleteCriticalSection(CriticalSection)
210 End Sub
211
212 'スレッドを生成
213 Sub BeginThread(pThread As *Thread,NowSp As *LONG_PTR)
214 EnterCriticalSection(CriticalSection)
215
216 '例外処理管理用オブジェクトを生成
217 Dim pException As *ExceptionService
218 pException = New ExceptionService
219
220 Dim i As Long
221 For i=0 To ELM(ThreadNum)
222 If ppobj_Thread[i] = 0 Then
223 ppobj_Thread[i] = pThread
224 pStackBase[i] = NowSp
225 ppException[i] = pException
226 Exit For
227 End If
228 Next
229
230 If i = ThreadNum Then
231 ppobj_Thread=realloc(ppobj_Thread,(ThreadNum+1)*SizeOf(*Thread))
232 ppobj_Thread[ThreadNum]=pThread
233 pStackBase=HeapReAlloc(_System_hProcessHeap,0,pStackBase,(ThreadNum+1)*SizeOf(LONG_PTR))
234 pStackBase[ThreadNum]=NowSp
235 ppException=HeapReAlloc(_System_hProcessHeap,0,ppException,(ThreadNum+1)*SizeOf(*ExceptionService))
236 ppException[ThreadNum]=pException
237 ThreadNum++
238 End If
239 LeaveCriticalSection(CriticalSection)
240 End Sub
241
242 'スレッドを終了
243 Sub EndThread(pThread As *Thread)
244 EnterCriticalSection(CriticalSection)
245 Dim i As Long
246 For i=0 To ELM(ThreadNum)
247 If ppobj_Thread[i] = pThread Then
248 If i = 0 Then
249 Delete pThread
250 End If
251 ppobj_Thread[i]=0
252 pStackBase[i]=0
253 Delete ppException[i]
254 ppException[i]=0
255 Exit For
256 End If
257 Next
258 LeaveCriticalSection(CriticalSection)
259 End Sub
260
261 ' すべてのスレッドを中断
262 Sub SuspendAllThread()
263 Dim i As Long
264 For i=0 To ELM(ThreadNum)
265 If ppobj_Thread[i] Then
266 ppobj_Thread[i]->Suspend()
267 End If
268 Next
269 End Sub
270
271 ' すべてのスレッドを再開
272 Sub ResumeAllThread()
273 Dim i As Long
274 For i=0 To ELM(ThreadNum)
275 If ppobj_Thread[i] Then
276 ppobj_Thread[i]->Resume()
277 End If
278 Next
279 End Sub
280
281 ' 自分以外のスレッドを中断
282 Sub SuspendAnotherThread()
283 Dim currentThread = Thread.CurrentThread()
284
285 Dim i As Long
286 For i=0 To ELM(ThreadNum)
287
288 If currentThread.Equals( ByVal ppobj_Thread[i] ) Then
289 Continue
290 End If
291
292 If ppobj_Thread[i] Then
293 ppobj_Thread[i]->Suspend()
294 End If
295 Next
296 End Sub
297
298 ' 自分以外のスレッドを再開
299 Sub ResumeAnotherThread()
300 Dim currentThread = Thread.CurrentThread()
301
302 Dim i As Long
303 For i=0 To ELM(ThreadNum)
304
305 If currentThread.Equals( ByVal ppobj_Thread[i] ) Then
306 Continue
307 End If
308
309 If ppobj_Thread[i] Then
310 ppobj_Thread[i]->Resume()
311 End If
312 Next
313 End Sub
314
315 'カレントスレッドを取得
316 Function CurrentThread(ByRef obj_Thread As Thread) As BOOL
317 Dim dwNowThreadId As DWord
318 dwNowThreadId=GetCurrentThreadId()
319
320 Dim i As Long
321 For i=0 To ELM(ThreadNum)
322 If ppobj_Thread[i]->ThreadId=dwNowThreadId Then
323 obj_Thread.Thread(ByVal ppobj_Thread[i])
324 Return 1
325 End If
326 Next
327
328 Return 0
329 End Function
330
331
332Private
333 '------------------------------------------
334 ' スレッド固有の例外処理制御
335 '------------------------------------------
336 ppException As **ExceptionService
337
338Public
339 Function GetCurrentException() As *ExceptionService
340 Dim dwNowThreadId As DWord
341 dwNowThreadId=GetCurrentThreadId()
342
343 Dim i As Long
344 For i=0 To ELM(ThreadNum)
345 If ppobj_Thread[i]->ThreadId=dwNowThreadId Then
346 Return ppException[i]
347 End If
348 Next
349
350 Return NULL
351 End Function
352End Class
353Dim _System_pobj_AllThreads As *_System_CThreadCollection
Note: See TracBrowser for help on using the repository browser.