Setup the initial thread %fs from a constructor.

This commit is contained in:
Alexandre Julliard 2000-05-01 21:21:31 +00:00
parent 1ca9be85f6
commit 8c21dfcf0f
5 changed files with 53 additions and 48 deletions

View File

@ -145,7 +145,7 @@ typedef struct _PDB
#define GPD_USERDATA ( 0) #define GPD_USERDATA ( 0)
extern DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset ); extern DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset );
void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value ); extern void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value );
extern DWORD WINAPI MapProcessHandle( HANDLE handle ); extern DWORD WINAPI MapProcessHandle( HANDLE handle );
/* memory/environ.c */ /* memory/environ.c */
@ -166,8 +166,6 @@ extern BOOL PROCESS_CreateUnixProcess( LPCSTR filename, LPCSTR cmd_line, LPCSTR
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info ); LPPROCESS_INFORMATION info );
extern void PROCESS_FreePDB( PDB *pdb );
extern void PROCESS_WalkProcess( void );
static inline PDB * WINE_UNUSED PROCESS_Current(void) static inline PDB * WINE_UNUSED PROCESS_Current(void)
{ {

View File

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

View File

@ -47,7 +47,7 @@ void MAIN_EmulatorRun( void )
if (PROFILE_GetWineIniString( "Wine", "GraphicsDriver", if (PROFILE_GetWineIniString( "Wine", "GraphicsDriver",
"x11drv", szGraphicsDriver, sizeof(szGraphicsDriver))) "x11drv", szGraphicsDriver, sizeof(szGraphicsDriver)))
{ {
if (!LoadLibraryA( szGraphicsDriver )) return FALSE; if (!LoadLibraryA( szGraphicsDriver )) ExitProcess(1);
} }
/* Load system DLLs into the initial process (and initialize them) */ /* Load system DLLs into the initial process (and initialize them) */
@ -109,7 +109,7 @@ int main( int argc, char *argv[] )
/* Initialize everything */ /* Initialize everything */
if (!MAIN_MainInit( argc, argv, FALSE )) return 1; if (!MAIN_MainInit( argc, argv, FALSE )) return 1;
if (!THREAD_InitStack( NtCurrentTeb(), PROCESS_Current(), 0, TRUE )) return 1; if (!THREAD_InitStack( NtCurrentTeb(), 0, TRUE )) return 1;
SIGNAL_Init(); /* reinitialize signal stack */ SIGNAL_Init(); /* reinitialize signal stack */
/* Initialize KERNEL */ /* Initialize KERNEL */

View File

@ -37,12 +37,10 @@ DECLARE_DEBUG_CHANNEL(relay);
DECLARE_DEBUG_CHANNEL(win32); DECLARE_DEBUG_CHANNEL(win32);
/* The initial process PDB */
static PDB initial_pdb;
static ENVDB initial_envdb; static ENVDB initial_envdb;
static STARTUPINFOA initial_startup; static STARTUPINFOA initial_startup;
static PDB *PROCESS_First = &initial_pdb; static PDB *PROCESS_First;
/*********************************************************************** /***********************************************************************
@ -213,7 +211,7 @@ static BOOL PROCESS_CreateEnvDB(void)
* *
* Free a PDB and all associated storage. * Free a PDB and all associated storage.
*/ */
void PROCESS_FreePDB( PDB *pdb ) static void PROCESS_FreePDB( PDB *pdb )
{ {
PDB **pptr = &PROCESS_First; PDB **pptr = &PROCESS_First;
@ -263,36 +261,38 @@ static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit )
BOOL PROCESS_Init( BOOL win32 ) BOOL PROCESS_Init( BOOL win32 )
{ {
struct init_process_request *req; struct init_process_request *req;
TEB *teb; PDB *pdb = PROCESS_Current();
/* Fill the initial process structure */ /* Fill the initial process structure */
initial_pdb.exit_code = STILL_ACTIVE; pdb->exit_code = STILL_ACTIVE;
initial_pdb.threads = 1; pdb->threads = 1;
initial_pdb.running_threads = 1; pdb->running_threads = 1;
initial_pdb.ring0_threads = 1; pdb->ring0_threads = 1;
initial_pdb.env_db = &initial_envdb; pdb->env_db = &initial_envdb;
initial_pdb.group = &initial_pdb; pdb->group = pdb;
initial_pdb.priority = 8; /* Normal */ pdb->priority = 8; /* Normal */
initial_pdb.flags = win32? 0 : PDB32_WIN16_PROC; pdb->winver = 0xffff; /* to be determined */
initial_pdb.winver = 0xffff; /* to be determined */ pdb->main_queue = INVALID_HANDLE_VALUE16;
initial_pdb.main_queue = INVALID_HANDLE_VALUE16;
initial_envdb.startup_info = &initial_startup; initial_envdb.startup_info = &initial_startup;
teb = THREAD_Init( &initial_pdb ); PROCESS_First = pdb;
if (!win32)
{
pdb->flags = PDB32_WIN16_PROC;
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
}
/* Setup the server connection */ /* Setup the server connection */
teb->socket = CLIENT_InitServer(); NtCurrentTeb()->socket = CLIENT_InitServer();
if (CLIENT_InitThread()) return FALSE; if (CLIENT_InitThread()) return FALSE;
/* Initialize virtual memory management */
if (!VIRTUAL_Init()) return FALSE;
/* Retrieve startup info from the server */ /* Retrieve startup info from the server */
req = get_req_buffer(); req = get_req_buffer();
req->ldt_copy = ldt_copy; req->ldt_copy = ldt_copy;
req->ldt_flags = ldt_flags_copy; req->ldt_flags = ldt_flags_copy;
req->ppid = getppid(); req->ppid = getppid();
if (server_call( REQ_INIT_PROCESS )) return FALSE; if (server_call( REQ_INIT_PROCESS )) return FALSE;
initial_pdb.exe_file = req->exe_file; pdb->exe_file = req->exe_file;
initial_startup.dwFlags = req->start_flags; initial_startup.dwFlags = req->start_flags;
initial_startup.wShowWindow = req->cmd_show; initial_startup.wShowWindow = req->cmd_show;
initial_envdb.hStdin = initial_startup.hStdInput = req->hstdin; initial_envdb.hStdin = initial_startup.hStdInput = req->hstdin;
@ -304,19 +304,19 @@ BOOL PROCESS_Init( BOOL win32 )
if (!SIGNAL_Init()) return FALSE; if (!SIGNAL_Init()) return FALSE;
/* Remember TEB selector of initial process for emergency use */ /* Remember TEB selector of initial process for emergency use */
SYSLEVEL_EmergencyTeb = teb->teb_sel; SYSLEVEL_EmergencyTeb = NtCurrentTeb()->teb_sel;
/* Create the system and process heaps */ /* Create the system and process heaps */
if (!HEAP_CreateSystemHeap()) return FALSE; if (!HEAP_CreateSystemHeap()) return FALSE;
initial_pdb.heap = HeapCreate( HEAP_GROWABLE, 0, 0 ); pdb->heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
/* Create the idle event for the initial process /* Create the idle event for the initial process
FIXME 1: Shouldn't we call UserSignalProc for the initial process too? FIXME 1: Shouldn't we call UserSignalProc for the initial process too?
FIXME 2: It seems to me that the initial pdb becomes never freed, so I don't now FIXME 2: It seems to me that the initial pdb becomes never freed, so I don't now
where to release the idle event for the initial process. where to release the idle event for the initial process.
*/ */
initial_pdb.idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL ); pdb->idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
initial_pdb.idle_event = ConvertToGlobalHandle ( initial_pdb.idle_event ); pdb->idle_event = ConvertToGlobalHandle ( pdb->idle_event );
/* Copy the parent environment */ /* Copy the parent environment */
if (!ENV_BuildEnvironment()) return FALSE; if (!ENV_BuildEnvironment()) return FALSE;
@ -325,7 +325,7 @@ BOOL PROCESS_Init( BOOL win32 )
if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE; if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
/* Initialize the critical sections */ /* Initialize the critical sections */
InitializeCriticalSection( &initial_pdb.crit_section ); InitializeCriticalSection( &pdb->crit_section );
InitializeCriticalSection( &initial_envdb.section ); InitializeCriticalSection( &initial_envdb.section );
return TRUE; return TRUE;
@ -467,7 +467,7 @@ void PROCESS_Init32( HFILE hFile, LPCSTR filename, LPCSTR cmd_line )
if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error; if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error;
/* allocate main thread stack */ /* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(), pdb, if (!THREAD_InitStack( NtCurrentTeb(),
PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE )) PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
goto error; goto error;
@ -516,7 +516,7 @@ void PROCESS_InitWinelib( int argc, char *argv[] )
if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error; if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error;
/* allocate main thread stack */ /* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(), pdb, if (!THREAD_InitStack( NtCurrentTeb(),
PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE )) PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
goto error; goto error;

View File

@ -37,6 +37,9 @@ DEFAULT_DEBUG_CHANNEL(thread);
/* TEB of the initial thread */ /* TEB of the initial thread */
static TEB initial_teb; static TEB initial_teb;
/* The initial process PDB */
static PDB initial_pdb;
/*********************************************************************** /***********************************************************************
* THREAD_IsWin16 * THREAD_IsWin16
*/ */
@ -75,18 +78,15 @@ TEB *THREAD_IdToTEB( DWORD id )
* *
* Initialization of a newly created TEB. * Initialization of a newly created TEB.
*/ */
static BOOL THREAD_InitTEB( TEB *teb, PDB *pdb ) static BOOL THREAD_InitTEB( TEB *teb )
{ {
teb->except = (void *)~0UL; teb->except = (void *)~0UL;
teb->htask16 = pdb->task;
teb->self = teb; teb->self = teb;
teb->tibflags = (pdb->flags & PDB32_WIN16_PROC) ? 0 : TEBF_WIN32; teb->tibflags = TEBF_WIN32;
teb->tls_ptr = teb->tls_array; teb->tls_ptr = teb->tls_array;
teb->process = pdb;
teb->exit_code = STILL_ACTIVE; teb->exit_code = STILL_ACTIVE;
teb->socket = -1; teb->socket = -1;
teb->stack_top = (void *)~0UL; teb->stack_top = (void *)~0UL;
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer); teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
teb->StaticUnicodeString.Buffer = (PWSTR)teb->StaticUnicodeBuffer; teb->StaticUnicodeString.Buffer = (PWSTR)teb->StaticUnicodeBuffer;
teb->teb_sel = SELECTOR_AllocBlock( teb, 0x1000, SEGMENT_DATA, TRUE, FALSE ); teb->teb_sel = SELECTOR_AllocBlock( teb, 0x1000, SEGMENT_DATA, TRUE, FALSE );
@ -121,7 +121,7 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb )
* *
* Allocate the stack of a thread. * Allocate the stack of a thread.
*/ */
TEB *THREAD_InitStack( TEB *teb, PDB *pdb, DWORD stack_size, BOOL alloc_stack16 ) TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 )
{ {
DWORD old_prot, total_size; DWORD old_prot, total_size;
DWORD page_size = VIRTUAL_GetPageSize(); DWORD page_size = VIRTUAL_GetPageSize();
@ -158,7 +158,7 @@ TEB *THREAD_InitStack( TEB *teb, PDB *pdb, DWORD stack_size, BOOL alloc_stack16
if (!teb) if (!teb)
{ {
teb = (TEB *)((char *)base + total_size - page_size); teb = (TEB *)((char *)base + total_size - page_size);
if (!THREAD_InitTEB( teb, pdb )) if (!THREAD_InitTEB( teb ))
{ {
VirtualFree( base, 0, MEM_RELEASE ); VirtualFree( base, 0, MEM_RELEASE );
return NULL; return NULL;
@ -202,13 +202,18 @@ error:
* *
* NOTES: The first allocated TEB on NT is at 0x7ffde000. * NOTES: The first allocated TEB on NT is at 0x7ffde000.
*/ */
TEB *THREAD_Init( struct _PDB *pdb ) void THREAD_Init(void)
{ {
if (!THREAD_InitTEB( &initial_teb, pdb )) return NULL; if (!initial_teb.self) /* do it only once */
SYSDEPS_SetCurThread( &initial_teb ); {
return &initial_teb; THREAD_InitTEB( &initial_teb );
assert( initial_teb.teb_sel );
initial_teb.process = &initial_pdb;
SYSDEPS_SetCurThread( &initial_teb );
}
} }
DECL_GLOBAL_CONSTRUCTOR(thread_init) { THREAD_Init(); }
/*********************************************************************** /***********************************************************************
* THREAD_Create * THREAD_Create
@ -218,9 +223,11 @@ TEB *THREAD_Create( PDB *pdb, int fd, DWORD stack_size, BOOL alloc_stack16 )
{ {
TEB *teb; TEB *teb;
if ((teb = THREAD_InitStack( NULL, pdb, stack_size, alloc_stack16 ))) if ((teb = THREAD_InitStack( NULL, stack_size, alloc_stack16 )))
{ {
teb->socket = fd; teb->tibflags = (pdb->flags & PDB32_WIN16_PROC) ? 0 : TEBF_WIN32;
teb->process = pdb;
teb->socket = fd;
fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */ fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
TRACE("(%p) succeeded\n", teb); TRACE("(%p) succeeded\n", teb);
} }