Commit f016752b authored by Alexandre Julliard's avatar Alexandre Julliard

Changed process initialisation to use the new server requests.

Started to move the process init to the right context, not finished yet.
parent f692d446
......@@ -96,10 +96,11 @@ typedef struct _THDB
CRITICAL_SECTION *sys_mutex[4];/* 1e8 Syslevel mutex pointers */
DWORD unknown6[2]; /* 1f8 Unknown */
/* The following are Wine-specific fields */
int socket; /* 200 Socket for server communication */
unsigned int seq; /* Server sequence number */
void *server_tid; /* Server id for this thread */
struct _THDB *next; /* Global thread list */
int socket; /* Socket for server communication */
unsigned int seq; /* Server sequence number */
void *server_tid; /* Server id for this thread */
void (*startup)(void); /* Thread startup routine */
struct _THDB *next; /* Global thread list */
} THDB;
/* The pseudo handle value returned by GetCurrentThread */
......@@ -115,16 +116,13 @@ extern THDB *pCurrentThread;
/* scheduler/thread.c */
extern THDB *THREAD_CreateInitialThread( struct _PDB *pdb );
extern THDB *THREAD_CreateInitialThread( struct _PDB *pdb, int server_fd );
extern THDB *THREAD_Create( struct _PDB *pdb, DWORD flags,
DWORD stack_size, BOOL alloc_stack16,
LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa,
int *server_thandle, int *server_phandle,
LPTHREAD_START_ROUTINE start_addr, LPVOID param );
LPSECURITY_ATTRIBUTES sa, int *server_handle );
extern THDB *THREAD_Current(void);
extern BOOL THREAD_IsWin16( THDB *thdb );
extern THDB *THREAD_IdToTHDB( DWORD id );
extern void THREAD_Start( THDB *thdb );
extern DWORD THREAD_TlsAlloc( THDB *thread );
/* scheduler/sysdeps.c */
......
......@@ -983,15 +983,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine,
CloseHandle( hFile );
}
/* Get hTask from process and start the task */
if ( retv )
{
PDB *pdb = PROCESS_IdToPDB( lpProcessInfo->dwProcessId );
if (pdb) TASK_StartTask( pdb->task );
}
return retv;
}
......
......@@ -272,46 +272,42 @@ unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd )
/***********************************************************************
* CLIENT_NewThread
* CLIENT_InitServer
*
* Send a new thread request.
* Start the server and create the initial socket pair.
*/
int CLIENT_NewThread( THDB *thdb,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
int *thandle, int *phandle )
int CLIENT_InitServer(void)
{
struct new_thread_request request;
struct new_thread_reply reply;
int fd[2];
char buffer[16];
extern void create_initial_thread( int fd );
if (socketpair( AF_UNIX, SOCK_STREAM, 0, fd ) == -1)
{
SetLastError( ERROR_TOO_MANY_OPEN_FILES ); /* FIXME */
return -1;
perror("socketpair");
exit(1);
}
request.pid = thdb->process->server_pid;
request.suspend = (thdb->flags & CREATE_SUSPENDED)? TRUE : FALSE;
request.tinherit = (tsa && (tsa->nLength>=sizeof(*tsa)) && tsa->bInheritHandle);
request.pinherit = (psa && (psa->nLength>=sizeof(*psa)) && psa->bInheritHandle);
CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error;
thdb->server_tid = reply.tid;
thdb->process->server_pid = reply.pid;
if (thdb->socket != -1) close( thdb->socket );
thdb->socket = fd[0];
thdb->seq = 0; /* reset the sequence number for the new fd */
fcntl( fd[0], F_SETFD, 1 ); /* set close on exec flag */
if (thandle) *thandle = reply.thandle;
else if (reply.thandle != -1) CloseHandle( reply.thandle );
if (phandle) *phandle = reply.phandle;
else if (reply.phandle != -1) CloseHandle( reply.phandle );
return 0;
error:
close( fd[0] );
return -1;
switch(fork())
{
case -1: /* error */
perror("fork");
exit(1);
case 0: /* child */
close( fd[0] );
sprintf( buffer, "%d", fd[1] );
/*#define EXEC_SERVER*/
#ifdef EXEC_SERVER
execlp( "wineserver", "wineserver", buffer, NULL );
execl( "/usr/local/bin/wineserver", "wineserver", buffer, NULL );
execl( "./server/wineserver", "wineserver", buffer, NULL );
#endif
create_initial_thread( fd[1] );
exit(0);
default: /* parent */
close( fd[1] );
break;
}
return fd[0];
}
......@@ -322,16 +318,9 @@ int CLIENT_NewThread( THDB *thdb,
*/
int CLIENT_InitThread(void)
{
THDB *thdb = THREAD_Current();
struct init_thread_request init;
int len = strlen( thdb->process->env_db->cmd_line );
init.unix_pid = getpid();
len = MIN( len, MAX_MSG_LENGTH - sizeof(init) );
CLIENT_SendRequest( REQ_INIT_THREAD, -1, 2,
&init, sizeof(init),
thdb->process->env_db->cmd_line, len );
CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &init, sizeof(init) );
return CLIENT_WaitReply( NULL, NULL, 0 );
}
......
......@@ -179,6 +179,55 @@ static BOOL PROCESS_InheritEnvDB( PDB *pdb, LPCSTR cmd_line, LPCSTR env,
/***********************************************************************
* PROCESS_CreateEnvDB
*
* Create the env DB for a newly started process.
*/
static BOOL PROCESS_CreateEnvDB(void)
{
struct init_process_request req;
struct init_process_reply reply;
STARTUPINFOA *startup;
ENVDB *env_db;
PDB *pdb = PROCESS_Current();
/* Retrieve startup info from the server */
req.dummy = 0;
CLIENT_SendRequest( REQ_INIT_PROCESS, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
/* Allocate the env DB */
if (!(env_db = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB) )))
return FALSE;
pdb->env_db = env_db;
InitializeCriticalSection( &env_db->section );
/* Allocate and fill the startup info */
if (!(startup = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(STARTUPINFOA) )))
return FALSE;
pdb->env_db->startup_info = startup;
startup->dwFlags = reply.start_flags;
pdb->env_db->hStdin = startup->hStdInput = reply.hstdin;
pdb->env_db->hStdout = startup->hStdOutput = reply.hstdout;
pdb->env_db->hStderr = startup->hStdError = reply.hstderr;
#if 0 /* FIXME */
/* Copy the parent environment */
if (!ENV_InheritEnvironment( pdb, env )) return FALSE;
/* Copy the command line */
if (!(pdb->env_db->cmd_line = HEAP_strdupA( pdb->heap, 0, cmd_line )))
return FALSE;
#endif
return TRUE;
}
/***********************************************************************
* PROCESS_FreePDB
*
* Free a PDB and all associated storage.
......@@ -191,7 +240,6 @@ void PROCESS_FreePDB( PDB *pdb )
while (*pptr && (*pptr != pdb)) pptr = &(*pptr)->next;
if (*pptr) *pptr = pdb->next;
if (pdb->heap && (pdb->heap != pdb->system_heap)) HeapDestroy( pdb->heap );
DeleteCriticalSection( &pdb->crit_section );
HeapFree( SystemHeap, 0, pdb );
}
......@@ -223,26 +271,15 @@ static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit )
/***********************************************************************
* PROCESS_FinishCreatePDB
*
* Second part of CreatePDB
*/
static BOOL PROCESS_FinishCreatePDB( PDB *pdb )
{
InitializeCriticalSection( &pdb->crit_section );
/* Allocate the event */
if (!(pdb->load_done_evt = CreateEventA( NULL, TRUE, FALSE, NULL )))
return FALSE;
return TRUE;
}
/***********************************************************************
* PROCESS_Init
*/
BOOL PROCESS_Init(void)
{
THDB *thdb;
int server_fd;
/* Start the server */
server_fd = CLIENT_InitServer();
/* Fill the initial process structure */
initial_pdb.exit_code = 0x103; /* STILL_ACTIVE */
......@@ -255,8 +292,8 @@ BOOL PROCESS_Init(void)
/* Initialize virtual memory management */
if (!VIRTUAL_Init()) return FALSE;
/* Create the initial thread structure */
if (!(thdb = THREAD_CreateInitialThread( &initial_pdb ))) return FALSE;
/* Create the initial thread structure and socket pair */
if (!(thdb = THREAD_CreateInitialThread( &initial_pdb, server_fd ))) return FALSE;
/* Remember TEB selector of initial process for emergency use */
SYSLEVEL_EmergencyTeb = thdb->teb_sel;
......@@ -270,16 +307,83 @@ BOOL PROCESS_Init(void)
/* Initialize the first thread */
if (CLIENT_InitThread()) return FALSE;
if (!PROCESS_FinishCreatePDB( &initial_pdb )) return FALSE;
/* Create the SEGPTR heap */
if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
/* Initialize the first process critical section */
InitializeCriticalSection( &initial_pdb.crit_section );
return TRUE;
}
/***********************************************************************
* PROCESS_Start
*
* Startup routine of a new process. Called in the context of the new process.
*/
void PROCESS_Start(void)
{
DWORD size, commit;
UINT cmdShow = 0;
LPTHREAD_START_ROUTINE entry;
THDB *thdb = THREAD_Current();
PDB *pdb = thdb->process;
NE_MODULE *pModule = (NE_MODULE *)thdb->entry_arg; /* hack */
/* Initialize the critical section */
InitializeCriticalSection( &pdb->crit_section );
/* Create the heap */
size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfHeapReserve;
commit = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfHeapCommit;
if (!(pdb->heap = HeapCreate( HEAP_GROWABLE, size, commit ))) goto error;
pdb->heap_list = pdb->heap;
/* Create the environment db */
if (!PROCESS_CreateEnvDB()) goto error;
#if 0
if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
cmdShow = pdb->env_db->startup_info->wShowWindow;
if (!TASK_Create( thdb, pModule, 0, 0, cmdShow )) goto error;
#endif
/* Map system DLLs into this process (from initial process) */
/* FIXME: this is a hack */
pdb->modref_list = PROCESS_Initial()->modref_list;
/* Create 32-bit MODREF */
{
OFSTRUCT *ofs = (OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo);
if (!PE_CreateModule( pModule->module32, ofs, 0, FALSE )) goto error;
}
/* Initialize thread-local storage */
PE_InitTls( thdb );
if (PE_HEADER(pModule->module32)->OptionalHeader.Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI)
AllocConsole();
/* Now call the entry point */
MODULE_InitializeDLLs( 0, DLL_PROCESS_ATTACH, (LPVOID)-1 );
entry = (LPTHREAD_START_ROUTINE)RVA_PTR(pModule->module32,
OptionalHeader.AddressOfEntryPoint);
TRACE(relay, "(entryproc=%p)\n", entry );
ExitProcess( entry(NULL) );
error:
ExitProcess(1);
}
/***********************************************************************
* PROCESS_Create
*
* Create a new process database and associated info.
......@@ -291,7 +395,9 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
PROCESS_INFORMATION *info )
{
DWORD size, commit;
int server_thandle, server_phandle;
int server_thandle;
struct new_process_request req;
struct new_process_reply reply;
UINT cmdShow = 0;
THDB *thdb = NULL;
PDB *parent = PROCESS_Current();
......@@ -299,7 +405,33 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
if (!pdb) return NULL;
info->hThread = info->hProcess = INVALID_HANDLE_VALUE;
if (!PROCESS_FinishCreatePDB( pdb )) goto error;
/* Create the process on the server side */
req.inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
req.inherit_all = inherit;
req.start_flags = startup->dwFlags;
if (startup->dwFlags & STARTF_USESTDHANDLES)
{
req.hstdin = startup->hStdInput;
req.hstdout = startup->hStdOutput;
req.hstderr = startup->hStdError;
}
else
{
req.hstdin = GetStdHandle( STD_INPUT_HANDLE );
req.hstdout = GetStdHandle( STD_OUTPUT_HANDLE );
req.hstderr = GetStdHandle( STD_ERROR_HANDLE );
}
CLIENT_SendRequest( REQ_NEW_PROCESS, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error;
pdb->server_pid = reply.pid;
info->hProcess = reply.handle;
info->dwProcessId = (DWORD)pdb->server_pid;
/* Initialize the critical section */
InitializeCriticalSection( &pdb->crit_section );
/* Create the heap */
......@@ -327,13 +459,9 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve;
else
size = 0;
if (!(thdb = THREAD_Create( pdb, 0L, size, hInstance == 0,
tsa, psa, &server_thandle, &server_phandle,
NULL, NULL )))
if (!(thdb = THREAD_Create( pdb, 0L, size, hInstance == 0, tsa, &server_thandle )))
goto error;
info->hThread = server_thandle;
info->hProcess = server_phandle;
info->dwProcessId = (DWORD)pdb->server_pid;
info->dwThreadId = (DWORD)thdb->server_tid;
/* Duplicate the standard handles */
......@@ -362,6 +490,10 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
pdb->modref_list = PROCESS_Initial()->modref_list;
/* Start the task */
TASK_StartTask( pdb->task );
return pdb;
error:
......@@ -381,12 +513,13 @@ void WINAPI ExitProcess( DWORD status )
TDB *pTask = (TDB *)GlobalLock16( pdb->task );
if ( pTask ) pTask->nEvents++;
MODULE_InitializeDLLs( 0, DLL_PROCESS_DETACH, NULL );
if ( pTask && pTask->thdb != THREAD_Current() )
ExitThread( status );
TerminateProcess( GetCurrentProcess(), status );
/* FIXME: should kill all running threads of this process */
pdb->exit_code = status;
FreeConsole();
__RESTORE_ES; /* Necessary for Pietrek's showseh example program */
TASK_KillCurrentTask( status );
......
......@@ -80,8 +80,14 @@ int *__h_errno_location()
*/
static void SYSDEPS_StartThread( THDB *thdb )
{
SET_FS( thdb->teb_sel );
THREAD_Start( thdb );
struct init_thread_request init;
SET_CUR_THREAD( thdb );
init.unix_pid = getpid();
CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &init, sizeof(init) );
CLIENT_WaitReply( NULL, NULL, 0 );
thdb->startup();
_exit(0); /* should never get here */
}
#endif /* USE_THREADS */
......
......@@ -5,6 +5,7 @@
*/
#include <assert.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
......@@ -94,8 +95,7 @@ THDB *THREAD_IdToTHDB( DWORD id )
* Initialization of a newly created THDB.
*/
static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16,
LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa,
int *server_thandle, int *server_phandle )
LPSECURITY_ATTRIBUTES sa )
{
DWORD old_prot;
......@@ -136,11 +136,6 @@ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16,
0x10000 - sizeof(STACK16FRAME) );
}
/* Create the thread socket */
if (CLIENT_NewThread( thdb, tsa, psa, server_thandle, server_phandle ))
goto error;
/* Create the thread event */
if (!(thdb->event = CreateEventA( NULL, FALSE, FALSE, NULL ))) goto error;
......@@ -148,7 +143,6 @@ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16,
return TRUE;
error:
if (thdb->socket != -1) close( thdb->socket );
if (thdb->event) CloseHandle( thdb->event );
if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE );
......@@ -189,51 +183,16 @@ void THREAD_FreeTHDB( THDB *thdb )
*
* Create the initial thread.
*/
THDB *THREAD_CreateInitialThread( PDB *pdb )
THDB *THREAD_CreateInitialThread( PDB *pdb, int server_fd )
{
int fd[2];
char buffer[16];
extern void server_init( int fd );
extern void select_loop(void);
initial_thdb.process = pdb;
initial_thdb.teb.except = (void *)-1;
initial_thdb.teb.self = &initial_thdb.teb;
initial_thdb.teb.flags = (pdb->flags & PDB32_WIN16_PROC)? 0 : TEBF_WIN32;
initial_thdb.teb.flags = TEBF_WIN32;
initial_thdb.teb.tls_ptr = initial_thdb.tls_array;
initial_thdb.teb.process = pdb;
initial_thdb.exit_code = 0x103; /* STILL_ACTIVE */
initial_thdb.socket = -1;
/* Start the server */
if (socketpair( AF_UNIX, SOCK_STREAM, 0, fd ) == -1)
{
perror("socketpair");
exit(1);
}
switch(fork())
{
case -1: /* error */
perror("fork");
exit(1);
case 0: /* child */
close( fd[0] );
sprintf( buffer, "%d", fd[1] );
/*#define EXEC_SERVER*/
#ifdef EXEC_SERVER
execlp( "wineserver", "wineserver", buffer, NULL );
execl( "/usr/local/bin/wineserver", "wineserver", buffer, NULL );
execl( "./server/wineserver", "wineserver", buffer, NULL );
#endif
server_init( fd[1] );
select_loop();
exit(0);
default: /* parent */
initial_thdb.socket = fd[0];
close( fd[1] );
break;
}
initial_thdb.socket = server_fd;
/* Allocate the TEB selector (%fs register) */
......@@ -248,8 +207,7 @@ THDB *THREAD_CreateInitialThread( PDB *pdb )
/* Now proceed with normal initialization */
if (!THREAD_InitTHDB( &initial_thdb, 0, TRUE,
NULL, NULL, NULL, NULL )) return NULL;
if (!THREAD_InitTHDB( &initial_thdb, 0, TRUE, NULL )) return NULL;
return &initial_thdb;
}
......@@ -258,10 +216,12 @@ THDB *THREAD_CreateInitialThread( PDB *pdb )
* THREAD_Create
*/
THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa,
int *server_thandle, int *server_phandle,
LPTHREAD_START_ROUTINE start_addr, LPVOID param )
LPSECURITY_ATTRIBUTES sa, int *server_handle )
{
struct new_thread_request request;
struct new_thread_reply reply = { NULL, -1 };
int fd[2];
THDB *thdb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(THDB) );
if (!thdb) return NULL;
thdb->process = pdb;
......@@ -273,8 +233,6 @@ THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16
thdb->teb.process = pdb;
thdb->exit_code = 0x103; /* STILL_ACTIVE */
thdb->flags = flags;
thdb->entry_point = start_addr;
thdb->entry_arg = param;
thdb->socket = -1;
/* Allocate the TEB selector (%fs register) */
......@@ -283,19 +241,39 @@ THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16
TRUE, FALSE );
if (!thdb->teb_sel) goto error;
/* Do the rest of the initialization */
/* Create the socket pair for server communication */
if (!THREAD_InitTHDB( thdb, stack_size, alloc_stack16,
tsa, psa, server_thandle, server_phandle ))
if (socketpair( AF_UNIX, SOCK_STREAM, 0, fd ) == -1)
{
SetLastError( ERROR_TOO_MANY_OPEN_FILES ); /* FIXME */
goto error;
}
thdb->socket = fd[0];
fcntl( fd[0], F_SETFD, 1 ); /* set close on exec flag */
/* Create the thread on the server side */
request.pid = thdb->process->server_pid;
request.suspend = ((thdb->flags & CREATE_SUSPENDED) != 0);
request.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error;
thdb->server_tid = reply.tid;
*server_handle = reply.handle;
/* Do the rest of the initialization */
if (!THREAD_InitTHDB( thdb, stack_size, alloc_stack16, sa )) goto error;
thdb->next = THREAD_First;
THREAD_First = thdb;
PE_InitTls( thdb );
return thdb;
error:
if (reply.handle != -1) CloseHandle( reply.handle );
if (thdb->teb_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 );
HeapFree( SystemHeap, 0, thdb );
if (thdb->socket != -1) close( thdb->socket );
return NULL;
}
......@@ -305,11 +283,10 @@ error:
*
* Start execution of a newly created thread. Does not return.
*/
void THREAD_Start( THDB *thdb )
static void THREAD_Start(void)
{
THDB *thdb = THREAD_Current();
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)thdb->entry_point;
assert( THREAD_Current() == thdb );
CLIENT_InitThread();
MODULE_InitializeDLLs( 0, DLL_THREAD_ATTACH, NULL );
ExitThread( func( thdb->entry_arg ) );
}
......@@ -323,9 +300,11 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
DWORD flags, LPDWORD id )
{
int handle = -1;
THDB *thread = THREAD_Create( PROCESS_Current(), flags, stack,
TRUE, sa, NULL, &handle, NULL, start, param );
THDB *thread = THREAD_Create( PROCESS_Current(), flags, stack, TRUE, sa, &handle );
if (!thread) return INVALID_HANDLE_VALUE;
thread->entry_point = start;
thread->entry_arg = param;
thread->startup = THREAD_Start;
if (SYSDEPS_SpawnThread( thread ) == -1)
{
CloseHandle( handle );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment