From 9ee9efff1b1dd782c6ea8dc9abd1734f0767015a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 28 Feb 2001 05:29:50 +0000 Subject: [PATCH] Use the standard CreateThread routine to create 16-bit tasks instead of duplicating the code. --- dlls/kernel/kernel_main.c | 8 +---- include/module.h | 1 + include/task.h | 5 +-- include/thread.h | 3 +- loader/ne/module.c | 56 ++++++++----------------------- loader/task.c | 85 +++++++++++++++++++++++++++++++++++++++-------- scheduler/process.c | 4 +-- scheduler/thread.c | 40 +++++++--------------- 8 files changed, 106 insertions(+), 96 deletions(-) diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c index 36f6f8cc00e..1cbd81441a9 100644 --- a/dlls/kernel/kernel_main.c +++ b/dlls/kernel/kernel_main.c @@ -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; } diff --git a/include/module.h b/include/module.h index 72683da7536..ed899877319 100644 --- a/include/module.h +++ b/include/module.h @@ -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); diff --git a/include/task.h b/include/task.h index 7a6b725392b..55309476f42 100644 --- a/include/task.h +++ b/include/task.h @@ -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); diff --git a/include/thread.h b/include/thread.h index faf7ba8d3fd..7d84170ee02 100644 --- a/include/thread.h +++ b/include/thread.h @@ -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 ); diff --git a/loader/ne/module.c b/loader/ne/module.c index 7985ec5c60a..3914ca28cc7 100644 --- a/loader/ne/module.c +++ b/loader/ne/module.c @@ -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 */ } /*********************************************************************** diff --git a/loader/task.c b/loader/task.c index a9661c47c4e..ac86874ca71 100644 --- a/loader/task.c +++ b/loader/task.c @@ -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; } diff --git a/scheduler/process.c b/scheduler/process.c index e7e7428ceb8..482cedb0d6d 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -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 ); diff --git a/scheduler/thread.c b/scheduler/thread.c index f8424a2f814..77daaacf8ed 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -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) { -- 2.11.4.GIT