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

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

Don't allocate selectors anymore. Allocate tiled memory and call Dos32FlatToSel; Get default stack size from PE header; Thread handles not closed properly

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