source: trunk/src/kernel32/hmthread.cpp@ 8919

Last change on this file since 8919 was 8919, checked in by sandervl, 23 years ago

keep suspend count for threads

File size: 10.6 KB
Line 
1/* $Id: hmthread.cpp,v 1.15 2002-07-26 10:47:19 sandervl Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 * Win32 thread handle class
7 *
8 *
9 * TODO: Handle is not destroyed when thread terminates (or else GetExitCodeThread won't work)
10 * Create thread token during thread creation??
11 * Fix for WaitForSingleObject when thread is already terminated, but
12 * WaitForMultipleObjects can still fail!
13 * WaitForSingle/MultipleObjects needs to be rewritten! (not using
14 * Open32)
15 *
16 ************************************************************************************
17 * NOTE: If we ever decide to allocate our own stack, then we MUST use VirtualAlloc!!!!
18 * (alignment reasons)
19 ************************************************************************************
20 *
21 * Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
22 *
23 */
24#include <os2win.h>
25#include <stdlib.h>
26#include <string.h>
27#include <misc.h>
28#include <wprocess.h>
29
30#include <HandleManager.H>
31#include "HMThread.h"
32#include "oslibdos.h"
33
34#include <win\thread.h>
35#include "thread.h"
36#include "asmutil.h"
37
38#define DBG_LOCALLOG DBG_hmthread
39#include "dbglocal.h"
40
41
42//******************************************************************************
43//******************************************************************************
44HANDLE HMDeviceThreadClass::CreateThread(PHMHANDLEDATA pHMHandleData,
45 LPSECURITY_ATTRIBUTES lpsa,
46 DWORD cbStack,
47 LPTHREAD_START_ROUTINE lpStartAddr,
48 LPVOID lpvThreadParm,
49 DWORD fdwCreate,
50 LPDWORD lpIDThread,
51 BOOL fFirstThread)
52{
53 Win32Thread *winthread;
54 DWORD threadid;
55 HANDLE hThread = pHMHandleData->hHMHandle;
56
57 if(lpIDThread == NULL) {
58 lpIDThread = &threadid;
59 }
60 pHMHandleData->dwInternalType = HMTYPE_THREAD;
61 pHMHandleData->dwUserData = THREAD_ALIVE;
62
63 //SvL: This doesn't really create a thread, but only sets up the
64 // handle of thread 0
65 if(fFirstThread) {
66 pHMHandleData->hHMHandle = O32_GetCurrentThread(); //return Open32 handle of thread
67 return pHMHandleData->hHMHandle;
68 }
69 winthread = new Win32Thread(lpStartAddr, lpvThreadParm, fdwCreate, hThread);
70
71 if(winthread == 0) {
72 DebugInt3();
73 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
74 return(0);
75 }
76 // @@@PH Note: with debug code enabled, ODIN might request more stack space!
77 //SvL: Also need more stack in release build (RealPlayer 7 sometimes runs
78 // out of stack
79 if (cbStack > 0)
80 cbStack <<= 1; // double stack
81 else
82 cbStack = 1048576; // per default 1MB stack per thread
83
84 //************************************************************************************
85 //NOTE: If we ever decide to allocate our own stack, then we MUST use VirtualAlloc!!!!
86 // (alignment reasons)
87 //************************************************************************************
88 pHMHandleData->hHMHandle = O32_CreateThread(lpsa, cbStack, winthread->GetOS2Callback(),
89 (LPVOID)winthread, fdwCreate, lpIDThread);
90
91 *lpIDThread = MAKE_THREADID(O32_GetCurrentProcessId(), *lpIDThread);
92
93 TEB *teb = GetTEBFromThreadHandle(hThread);
94 if(teb) {
95 //store thread id in TEB
96 teb->o.odin.threadId = *lpIDThread;
97 teb->o.odin.dwSuspend = (fdwCreate & CREATE_SUSPENDED) ? 1 : 0;
98 }
99 else DebugInt3();
100
101 dprintf(("CreateThread created %08x, id %x", pHMHandleData->hHMHandle, *lpIDThread));
102
103 return pHMHandleData->hHMHandle;
104}
105//******************************************************************************
106//******************************************************************************
107DWORD HMDeviceThreadClass::SuspendThread(HANDLE hThread, PHMHANDLEDATA pHMHandleData)
108{
109 DWORD dwSuspend;
110
111 TEB *teb = GetTEBFromThreadHandle(hThread);
112 if(teb) {
113 teb->o.odin.dwSuspend++;
114 dprintf(("SuspendThread %08xh): count %d", pHMHandleData->hHMHandle, teb->o.odin.dwSuspend));
115 }
116 dwSuspend = O32_SuspendThread(pHMHandleData->hHMHandle);
117 if(dwSuspend == -1) {
118 teb->o.odin.dwSuspend--;
119 dprintf(("!ERROR!: SuspendThread FAILED"));
120 }
121 return dwSuspend;
122}
123//******************************************************************************
124//******************************************************************************
125DWORD HMDeviceThreadClass::ResumeThread(HANDLE hThread, PHMHANDLEDATA pHMHandleData)
126{
127 DWORD dwSuspend;
128 TEB *teb = GetTEBFromThreadHandle(hThread);
129 if(teb) {
130 teb->o.odin.dwSuspend--;
131 dprintf(("ResumeThread (%08xh) : count %d", pHMHandleData->hHMHandle, teb->o.odin.dwSuspend));
132 }
133 dwSuspend = O32_ResumeThread(pHMHandleData->hHMHandle);
134 if(dwSuspend == -1) {
135 teb->o.odin.dwSuspend++;
136 dprintf(("!ERROR!: ResumeThread FAILED"));
137 }
138 return dwSuspend;
139}
140//******************************************************************************
141//******************************************************************************
142INT HMDeviceThreadClass::GetThreadPriority(HANDLE hThread, PHMHANDLEDATA pHMHandleData)
143{
144 TEB *teb;
145
146 dprintf(("GetThreadPriority(%08xh)\n", pHMHandleData->hHMHandle));
147
148 teb = GetTEBFromThreadHandle(hThread);
149 if(teb == NULL) {
150 dprintf(("!WARNING!: TEB not found!!"));
151 SetLastError(ERROR_INVALID_HANDLE);
152 return THREAD_PRIORITY_ERROR_RETURN;
153 }
154 return teb->delta_priority;
155}
156//******************************************************************************
157//******************************************************************************
158BOOL HMDeviceThreadClass::SetThreadPriority(HANDLE hThread, PHMHANDLEDATA pHMHandleData, int priority)
159{
160 TEB *teb;
161
162 dprintf(("SetThreadPriority (%08xh,%08xh)", pHMHandleData->hHMHandle, priority));
163
164 teb = GetTEBFromThreadHandle(hThread);
165 if(teb == NULL) {
166 dprintf(("!WARNING!: TEB not found!!"));
167 SetLastError(ERROR_INVALID_HANDLE);
168 return THREAD_PRIORITY_ERROR_RETURN;
169 }
170 DWORD ret = OSLibDosSetPriority(ODIN_TO_OS2_THREADID(teb->o.odin.threadId), priority);
171 if(ret == ERROR_SUCCESS) {
172 teb->delta_priority = priority;
173 return TRUE;
174 }
175 else {
176 dprintf(("DosSetPriority failed with rc %d", ret));
177 return FALSE;
178 }
179}
180//******************************************************************************
181//TODO: Implement this??
182//******************************************************************************
183BOOL HMDeviceThreadClass::GetThreadContext(HANDLE hThread, PHMHANDLEDATA pHMHandleData, PCONTEXT lpContext)
184{
185 dprintf(("GetThreadContext NOT IMPLEMENTED!! (TRUE)\n"));
186 memset(lpContext, 0, sizeof(CONTEXT));
187
188 /* make up some plausible values for segment registers */
189 lpContext->SegCs = getCS();
190 lpContext->SegDs = getDS();
191 lpContext->SegSs = getSS();
192 lpContext->SegEs = getES();
193 lpContext->SegGs = getGS();
194 lpContext->SegFs = GetFS();
195
196 return TRUE;
197}
198//******************************************************************************
199//TODO: Implement this??
200//******************************************************************************
201BOOL HMDeviceThreadClass::SetThreadContext(HANDLE hThread, PHMHANDLEDATA pHMHandleData, const CONTEXT *lpContext)
202{
203 dprintf(("SetThreadContext NOT IMPLEMENTED!!\n"));
204
205 return FALSE;
206}
207//******************************************************************************
208//******************************************************************************
209BOOL HMDeviceThreadClass::TerminateThread(HANDLE hThread, PHMHANDLEDATA pHMHandleData, DWORD exitcode)
210{
211 dprintf(("TerminateThread (%08xh,%08xh)\n",
212 pHMHandleData->hHMHandle,
213 exitcode));
214
215 pHMHandleData->dwUserData = THREAD_TERMINATED;
216 return O32_TerminateThread(pHMHandleData->hHMHandle, exitcode);
217}
218//******************************************************************************
219//******************************************************************************
220BOOL HMDeviceThreadClass::SetThreadTerminated(HANDLE hThread, PHMHANDLEDATA pHMHandleData)
221{
222 pHMHandleData->dwUserData = THREAD_TERMINATED;
223 return TRUE;
224}
225//******************************************************************************
226//******************************************************************************
227BOOL HMDeviceThreadClass::GetExitCodeThread(HANDLE hThread, PHMHANDLEDATA pHMHandleData, LPDWORD lpExitCode)
228{
229 dprintf(("GetExitCodeThread (%08xh,%08xh)\n",
230 pHMHandleData->hHMHandle,
231 lpExitCode));
232
233#if 0
234 if(pHMHandleData->dwUserData == THREAD_ALIVE) {
235 lpExitCode == STILL_ALIVE;
236 return TRUE;
237 }
238#endif
239 return O32_GetExitCodeThread(pHMHandleData->hHMHandle, lpExitCode);
240}
241//******************************************************************************
242//******************************************************************************
243BOOL HMDeviceThreadClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
244{
245 return TRUE;
246}
247//******************************************************************************
248//******************************************************************************
249DWORD HMDeviceThreadClass::WaitForSingleObject(PHMHANDLEDATA pHMHandleData,
250 DWORD dwTimeout)
251{
252 dprintf(("HMThread::WaitForSingleObject (%08xh,%08xh)\n",
253 pHMHandleData->hHMHandle,
254 dwTimeout));
255
256 //This doesn't work very well in Open32 (object's state never signaled)
257 if(pHMHandleData->dwUserData == THREAD_TERMINATED) {
258 return WAIT_OBJECT_0;
259 }
260 return HMDeviceOpen32Class::WaitForSingleObject(pHMHandleData, dwTimeout);
261}
262//******************************************************************************
263//******************************************************************************
264DWORD HMDeviceThreadClass::WaitForSingleObjectEx(PHMHANDLEDATA pHMHandleData,
265 DWORD dwTimeout,
266 BOOL fAlertable)
267{
268 if(pHMHandleData->dwUserData == THREAD_TERMINATED) {
269 return WAIT_OBJECT_0;
270 }
271 return HMDeviceOpen32Class::WaitForSingleObjectEx(pHMHandleData, dwTimeout, fAlertable);
272}
273//******************************************************************************
274//******************************************************************************
Note: See TracBrowser for help on using the repository browser.