mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-05 19:39:40 +00:00
Changed process initialisation to use the new server requests.
Started to move the process init to the right context, not finished yet.
This commit is contained in:
parent
f692d44607
commit
f016752b45
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -178,6 +178,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
|
||||
*
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -222,27 +270,16 @@ 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,15 +307,82 @@ 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
|
||||
*
|
||||
|
@ -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;
|
||||
|
||||
/* Create the socket pair for server communication */
|
||||
|
||||
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,
|
||||
tsa, psa, server_thandle, server_phandle ))
|
||||
goto error;
|
||||
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 );
|
||||
|
|
Loading…
Reference in a new issue