Use the standard CreateThread routine to create 16-bit tasks instead

of duplicating the code.
This commit is contained in:
Alexandre Julliard 2001-02-28 05:29:50 +00:00
parent e1635e9a63
commit 9ee9efff1b
8 changed files with 106 additions and 96 deletions

View file

@ -26,8 +26,6 @@ extern void COMM_Init(void);
static BOOL process_attach(void)
{
HMODULE16 hModule;
STARTUPINFOA startup_info;
UINT cmdShow = 1; /* SW_SHOWNORMAL but we don't want to include winuser.h here */
/* Setup codepage info */
CODEPAGE_Init();
@ -83,11 +81,7 @@ static BOOL process_attach(void)
if (!DOSCONF_ReadConfig()) return FALSE;
/* Create 16-bit task */
GetStartupInfoA( &startup_info );
if (startup_info.dwFlags & STARTF_USESHOWWINDOW) cmdShow = startup_info.wShowWindow;
if (!TASK_Create( (NE_MODULE *)GlobalLock16( MapHModuleLS(GetModuleHandleA(0)) ),
cmdShow, NtCurrentTeb(), NULL, 0 ))
return FALSE;
TASK_CreateMainTask();
return TRUE;
}

View file

@ -186,6 +186,7 @@ extern FARPROC16 WINAPI NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal );
extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop );
extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
extern HANDLE NE_OpenFile( NE_MODULE *pModule );
extern DWORD NE_StartTask(void);
/* loader/ne/resource.c */
extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);

View file

@ -145,8 +145,9 @@ typedef struct _THHOOK
extern THHOOK *pThhook;
extern BOOL TASK_Create( struct _NE_MODULE *pModule, UINT16 cmdShow,
struct _TEB *teb, LPCSTR cmdline, BYTE len );
extern void TASK_CreateMainTask(void);
extern HTASK TASK_SpawnTask( struct _NE_MODULE *pModule, WORD cmdShow,
LPCSTR cmdline, BYTE len, HANDLE *hThread );
extern void TASK_ExitTask(void);
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
extern void TASK_Reschedule(void);

View file

@ -125,8 +125,7 @@ typedef struct _TEB
/* scheduler/thread.c */
extern void THREAD_Init(void);
extern TEB *THREAD_Create( int fd, DWORD stack_size, BOOL alloc_stack16 );
extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 );
extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size );
extern BOOL THREAD_IsWin16( TEB *thdb );
extern TEB *THREAD_IdToTEB( DWORD id );

View file

@ -24,7 +24,6 @@
#include "stackframe.h"
#include "debugtools.h"
#include "loadorder.h"
#include "server.h"
DEFAULT_DEBUG_CHANNEL(module);
DECLARE_DEBUG_CHANNEL(loaddll);
@ -46,7 +45,6 @@ static NE_MODULE *pCachedModule = 0; /* Module cached by NE_OpenFile */
static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only );
static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep );
static void NE_InitProcess(void) WINE_NORETURN;
static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only );
@ -983,35 +981,13 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_
*/
static HINSTANCE16 NE_CreateThread( NE_MODULE *pModule, WORD cmdShow, LPCSTR cmdline )
{
TEB *teb = NULL;
HANDLE hThread = 0;
int socket = -1;
HTASK hTask;
HANDLE hThread;
TDB *pTask;
HTASK hTask;
HINSTANCE16 instance = 0;
SERVER_START_REQ( new_thread )
{
req->suspend = 0;
req->inherit = 0;
if (!SERVER_CALL_ERR())
{
hThread = req->handle;
socket = wine_server_recv_fd( hThread, 0 );
}
}
SERVER_END_REQ;
if (!hThread) return 0;
if (!(teb = THREAD_Create( socket, 0, FALSE ))) goto error;
teb->tibflags &= ~TEBF_WIN32;
teb->startup = NE_InitProcess;
/* Create a task for this process */
if (!TASK_Create( pModule, cmdShow, teb, cmdline + 1, *cmdline )) goto error;
hTask = teb->htask16;
if (SYSDEPS_SpawnThread( teb ) == -1) goto error;
if (!(hTask = TASK_SpawnTask( pModule, cmdShow, cmdline + 1, *cmdline, &hThread )))
return 0;
/* Post event to start the task */
PostEvent16( hTask );
@ -1033,13 +1009,8 @@ static HINSTANCE16 NE_CreateThread( NE_MODULE *pModule, WORD cmdShow, LPCSTR cmd
GlobalUnlock16( hTask );
} while (!instance);
return instance;
error:
/* FIXME: free TEB and task */
close( socket );
CloseHandle( hThread );
return 0; /* FIXME */
return instance;
}
@ -1138,9 +1109,11 @@ HINSTANCE16 NE_StartMain( LPCSTR name, HANDLE file )
/**********************************************************************
* NE_InitProcess
* NE_StartTask
*
* Startup code for a new 16-bit task.
*/
static void NE_InitProcess(void)
DWORD NE_StartTask(void)
{
TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
@ -1148,8 +1121,6 @@ static void NE_InitProcess(void)
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
WORD sp;
_EnterWin16Lock();
if ( pModule->count > 0 )
{
/* Second instance of an already loaded NE module */
@ -1184,8 +1155,11 @@ static void NE_InitProcess(void)
pTask->hInstance = hInstance;
pTask->hPrevInstance = hPrevInstance;
/* Free the previous stack selector */
FreeSelector16( SELECTOROF(pTask->teb->cur_stack) );
/* Use DGROUP for 16-bit stack */
if (!(sp = pModule->sp))
sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
sp &= ~1;
@ -1224,9 +1198,7 @@ static void NE_InitProcess(void)
wine_call_to_16_regs_short( &context, 0 );
ExitThread( LOWORD(context.Eax) );
}
_LeaveWin16Lock();
ExitThread( hInstance );
return hInstance; /* error code */
}
/***********************************************************************

View file

@ -218,7 +218,7 @@ static BOOL TASK_FreeThunk( HTASK16 hTask, SEGPTR thunk )
* by entering the Win16Lock while linking the task into the
* global task list.
*/
BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline, BYTE len )
static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline, BYTE len )
{
HTASK16 hTask;
TDB *pTask;
@ -227,7 +227,7 @@ BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline,
/* Allocate the task structure */
hTask = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, sizeof(TDB) );
if (!hTask) return FALSE;
if (!hTask) return NULL;
pTask = (TDB *)GlobalLock16( hTask );
FarSetOwner16( hTask, pModule->self );
@ -235,7 +235,7 @@ BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline,
pTask->hSelf = hTask;
if (teb->tibflags & TEBF_WIN32)
if (teb && teb->tibflags & TEBF_WIN32)
{
pTask->flags |= TDBF_WIN32;
pTask->hInstance = pModule->self;
@ -323,20 +323,15 @@ BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline,
if ( !(pTask->flags & TDBF_WIN32) )
NtCreateEvent( &pTask->hEvent, EVENT_ALL_ACCESS, NULL, TRUE, FALSE );
/* Enter task handle into thread and process */
/* Enter task handle into thread */
teb->htask16 = hTask;
if (teb) teb->htask16 = hTask;
if (!initial_task) initial_task = hTask;
/* Add the task to the linked list */
_EnterWin16Lock();
TASK_LinkTask( hTask );
_LeaveWin16Lock();
return TRUE;
return pTask;
}
/***********************************************************************
* TASK_DeleteTask
*/
@ -369,6 +364,70 @@ static void TASK_DeleteTask( HTASK16 hTask )
GlobalFreeAll16( hPDB );
}
/***********************************************************************
* TASK_CreateMainTask
*
* Create a task for the main (32-bit) process.
*/
void TASK_CreateMainTask(void)
{
TDB *pTask;
STARTUPINFOA startup_info;
UINT cmdShow = 1; /* SW_SHOWNORMAL but we don't want to include winuser.h here */
GetStartupInfoA( &startup_info );
if (startup_info.dwFlags & STARTF_USESHOWWINDOW) cmdShow = startup_info.wShowWindow;
pTask = TASK_Create( (NE_MODULE *)GlobalLock16( MapHModuleLS(GetModuleHandleA(0)) ),
cmdShow, NtCurrentTeb(), NULL, 0 );
if (!pTask)
{
ERR("could not create task for main process\n");
ExitProcess(1);
}
/* Add the task to the linked list */
/* (no need to get the win16 lock, we are the only thread at this point) */
TASK_LinkTask( pTask->hSelf );
}
/* startup routine for a new 16-bit thread */
static DWORD CALLBACK task_start( TDB *pTask )
{
DWORD ret;
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
NtCurrentTeb()->htask16 = pTask->hSelf;
_EnterWin16Lock();
TASK_LinkTask( pTask->hSelf );
pTask->teb = NtCurrentTeb();
ret = NE_StartTask();
_LeaveWin16Lock();
return ret;
}
/***********************************************************************
* TASK_SpawnTask
*
* Spawn a new 16-bit task.
*/
HTASK TASK_SpawnTask( NE_MODULE *pModule, WORD cmdShow, LPCSTR cmdline, BYTE len, HANDLE *hThread )
{
TDB *pTask;
if (!(pTask = TASK_Create( pModule, cmdShow, NULL, cmdline, len ))) return 0;
if (!(*hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)task_start, pTask, 0, NULL )))
{
TASK_DeleteTask( pTask->hSelf );
return 0;
}
return pTask->hSelf;
}
/***********************************************************************
* TASK_KillTask
*/
@ -525,7 +584,7 @@ void TASK_Reschedule(void)
{
hNewTask = pOldTask->hYieldTo;
pNewTask = (TDB *)GlobalLock16( hNewTask );
if( !pNewTask || !pNewTask->nEvents) hNewTask = 0;
if( !pNewTask || !pNewTask->nEvents || !pNewTask->teb) hNewTask = 0;
pOldTask->hYieldTo = 0;
}

View file

@ -520,7 +520,7 @@ void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win
found:
/* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(), stack_size, TRUE )) goto error;
if (!THREAD_InitStack( NtCurrentTeb(), stack_size )) goto error;
/* switch to the new stack */
SYSDEPS_SwitchToThreadStack( start_process );
@ -540,7 +540,7 @@ void PROCESS_InitWinelib( int argc, char *argv[] )
if (!process_init( argv )) exit(1);
/* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(), 0, TRUE )) ExitProcess( GetLastError() );
if (!THREAD_InitStack( NtCurrentTeb(), 0 )) ExitProcess( GetLastError() );
/* switch to the new stack */
SYSDEPS_SwitchToThreadStack( start_process );

View file

@ -131,7 +131,7 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb )
*
* Allocate the stack of a thread.
*/
TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 )
TEB *THREAD_InitStack( TEB *teb, DWORD stack_size )
{
DWORD old_prot, total_size;
DWORD page_size = getpagesize();
@ -169,7 +169,7 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 )
stack_size = (stack_size + (page_size - 1)) & ~(page_size - 1);
total_size = stack_size + SIGNAL_STACK_SIZE + 3 * page_size;
if (alloc_stack16) total_size += 0x10000;
total_size += 0x10000; /* 16-bit stack */
if (!teb) total_size += page_size;
if (!(base = VirtualAlloc( NULL, total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE )))
@ -199,12 +199,10 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 )
/* Allocate the 16-bit stack selector */
if (alloc_stack16)
{
teb->stack_sel = SELECTOR_AllocBlock( teb->stack_top, 0x10000, WINE_LDT_FLAGS_DATA );
if (!teb->stack_sel) goto error;
teb->cur_stack = MAKESEGPTR( teb->stack_sel, 0x10000 - sizeof(STACK16FRAME) );
}
teb->stack_sel = SELECTOR_AllocBlock( teb->stack_top, 0x10000, WINE_LDT_FLAGS_DATA );
if (!teb->stack_sel) goto error;
teb->cur_stack = MAKESEGPTR( teb->stack_sel, 0x10000 - sizeof(STACK16FRAME) );
return teb;
error:
@ -255,25 +253,6 @@ void THREAD_Init(void)
DECL_GLOBAL_CONSTRUCTOR(thread_init) { THREAD_Init(); }
/***********************************************************************
* THREAD_Create
*
*/
TEB *THREAD_Create( int fd, DWORD stack_size, BOOL alloc_stack16 )
{
TEB *teb;
if ((teb = THREAD_InitStack( NULL, stack_size, alloc_stack16 )))
{
teb->tibflags = TEBF_WIN32;
teb->process = NtCurrentTeb()->process;
teb->socket = fd;
fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
TRACE("(%p) succeeded\n", teb);
}
return teb;
}
/***********************************************************************
* THREAD_Start
@ -325,15 +304,20 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
SERVER_END_REQ;
if (!handle) return 0;
if (!(teb = THREAD_Create( socket, stack, TRUE )))
if (!(teb = THREAD_InitStack( NULL, stack )))
{
close( socket );
return 0;
}
teb->process = NtCurrentTeb()->process;
teb->socket = socket;
teb->entry_point = start;
teb->entry_arg = param;
teb->startup = THREAD_Start;
teb->htask16 = GetCurrentTask();
fcntl( socket, F_SETFD, 1 ); /* set close on exec flag */
if (id) *id = (DWORD)tid;
if (SYSDEPS_SpawnThread( teb ) == -1)
{