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)
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 );
/* memory/environ.c */
@ -166,8 +166,6 @@ extern BOOL PROCESS_CreateUnixProcess( LPCSTR filename, LPCSTR cmd_line, LPCSTR
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info );
extern void PROCESS_FreePDB( PDB *pdb );
extern void PROCESS_WalkProcess( void );
static inline PDB * WINE_UNUSED PROCESS_Current(void)
{

View File

@ -119,9 +119,9 @@ typedef struct _TEB
/* 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_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 TEB *THREAD_IdToTEB( DWORD id );

View File

@ -47,7 +47,7 @@ void MAIN_EmulatorRun( void )
if (PROFILE_GetWineIniString( "Wine", "GraphicsDriver",
"x11drv", szGraphicsDriver, sizeof(szGraphicsDriver)))
{
if (!LoadLibraryA( szGraphicsDriver )) return FALSE;
if (!LoadLibraryA( szGraphicsDriver )) ExitProcess(1);
}
/* Load system DLLs into the initial process (and initialize them) */
@ -109,7 +109,7 @@ int main( int argc, char *argv[] )
/* Initialize everything */
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 */
/* Initialize KERNEL */

View File

@ -37,12 +37,10 @@ DECLARE_DEBUG_CHANNEL(relay);
DECLARE_DEBUG_CHANNEL(win32);
/* The initial process PDB */
static PDB initial_pdb;
static ENVDB initial_envdb;
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.
*/
void PROCESS_FreePDB( PDB *pdb )
static void PROCESS_FreePDB( PDB *pdb )
{
PDB **pptr = &PROCESS_First;
@ -263,36 +261,38 @@ static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit )
BOOL PROCESS_Init( BOOL win32 )
{
struct init_process_request *req;
TEB *teb;
PDB *pdb = PROCESS_Current();
/* Fill the initial process structure */
initial_pdb.exit_code = STILL_ACTIVE;
initial_pdb.threads = 1;
initial_pdb.running_threads = 1;
initial_pdb.ring0_threads = 1;
initial_pdb.env_db = &initial_envdb;
initial_pdb.group = &initial_pdb;
initial_pdb.priority = 8; /* Normal */
initial_pdb.flags = win32? 0 : PDB32_WIN16_PROC;
initial_pdb.winver = 0xffff; /* to be determined */
initial_pdb.main_queue = INVALID_HANDLE_VALUE16;
pdb->exit_code = STILL_ACTIVE;
pdb->threads = 1;
pdb->running_threads = 1;
pdb->ring0_threads = 1;
pdb->env_db = &initial_envdb;
pdb->group = pdb;
pdb->priority = 8; /* Normal */
pdb->winver = 0xffff; /* to be determined */
pdb->main_queue = INVALID_HANDLE_VALUE16;
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 */
teb->socket = CLIENT_InitServer();
NtCurrentTeb()->socket = CLIENT_InitServer();
if (CLIENT_InitThread()) return FALSE;
/* Initialize virtual memory management */
if (!VIRTUAL_Init()) return FALSE;
/* Retrieve startup info from the server */
req = get_req_buffer();
req->ldt_copy = ldt_copy;
req->ldt_flags = ldt_flags_copy;
req->ppid = getppid();
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.wShowWindow = req->cmd_show;
initial_envdb.hStdin = initial_startup.hStdInput = req->hstdin;
@ -304,19 +304,19 @@ BOOL PROCESS_Init( BOOL win32 )
if (!SIGNAL_Init()) return FALSE;
/* 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 */
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
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
where to release the idle event for the initial process.
*/
initial_pdb.idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
initial_pdb.idle_event = ConvertToGlobalHandle ( initial_pdb.idle_event );
pdb->idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
pdb->idle_event = ConvertToGlobalHandle ( pdb->idle_event );
/* Copy the parent environment */
if (!ENV_BuildEnvironment()) return FALSE;
@ -325,7 +325,7 @@ BOOL PROCESS_Init( BOOL win32 )
if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
/* Initialize the critical sections */
InitializeCriticalSection( &initial_pdb.crit_section );
InitializeCriticalSection( &pdb->crit_section );
InitializeCriticalSection( &initial_envdb.section );
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;
/* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(), pdb,
if (!THREAD_InitStack( NtCurrentTeb(),
PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
goto error;
@ -516,7 +516,7 @@ void PROCESS_InitWinelib( int argc, char *argv[] )
if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error;
/* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(), pdb,
if (!THREAD_InitStack( NtCurrentTeb(),
PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
goto error;

View File

@ -37,6 +37,9 @@ DEFAULT_DEBUG_CHANNEL(thread);
/* TEB of the initial thread */
static TEB initial_teb;
/* The initial process PDB */
static PDB initial_pdb;
/***********************************************************************
* THREAD_IsWin16
*/
@ -75,18 +78,15 @@ TEB *THREAD_IdToTEB( DWORD id )
*
* 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->htask16 = pdb->task;
teb->self = teb;
teb->tibflags = (pdb->flags & PDB32_WIN16_PROC) ? 0 : TEBF_WIN32;
teb->tibflags = TEBF_WIN32;
teb->tls_ptr = teb->tls_array;
teb->process = pdb;
teb->exit_code = STILL_ACTIVE;
teb->socket = -1;
teb->stack_top = (void *)~0UL;
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
teb->StaticUnicodeString.Buffer = (PWSTR)teb->StaticUnicodeBuffer;
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.
*/
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 page_size = VIRTUAL_GetPageSize();
@ -158,7 +158,7 @@ TEB *THREAD_InitStack( TEB *teb, PDB *pdb, DWORD stack_size, BOOL alloc_stack16
if (!teb)
{
teb = (TEB *)((char *)base + total_size - page_size);
if (!THREAD_InitTEB( teb, pdb ))
if (!THREAD_InitTEB( teb ))
{
VirtualFree( base, 0, MEM_RELEASE );
return NULL;
@ -202,13 +202,18 @@ error:
*
* 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 */
{
THREAD_InitTEB( &initial_teb );
assert( initial_teb.teb_sel );
initial_teb.process = &initial_pdb;
SYSDEPS_SetCurThread( &initial_teb );
return &initial_teb;
}
}
DECL_GLOBAL_CONSTRUCTOR(thread_init) { THREAD_Init(); }
/***********************************************************************
* THREAD_Create
@ -218,8 +223,10 @@ TEB *THREAD_Create( PDB *pdb, int fd, DWORD stack_size, BOOL alloc_stack16 )
{
TEB *teb;
if ((teb = THREAD_InitStack( NULL, pdb, stack_size, alloc_stack16 )))
if ((teb = THREAD_InitStack( NULL, stack_size, alloc_stack16 )))
{
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 */
TRACE("(%p) succeeded\n", teb);