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

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

thread linking + create TEB before thread creation

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