Use the standard CreateThread routine to create 16-bit tasks instead
of duplicating the code.
This commit is contained in:
parent
e1635e9a63
commit
9ee9efff1b
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue