mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 13:27:35 +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
6 changed files with 245 additions and 149 deletions
|
@ -96,10 +96,11 @@ typedef struct _THDB
|
||||||
CRITICAL_SECTION *sys_mutex[4];/* 1e8 Syslevel mutex pointers */
|
CRITICAL_SECTION *sys_mutex[4];/* 1e8 Syslevel mutex pointers */
|
||||||
DWORD unknown6[2]; /* 1f8 Unknown */
|
DWORD unknown6[2]; /* 1f8 Unknown */
|
||||||
/* The following are Wine-specific fields */
|
/* The following are Wine-specific fields */
|
||||||
int socket; /* 200 Socket for server communication */
|
int socket; /* Socket for server communication */
|
||||||
unsigned int seq; /* Server sequence number */
|
unsigned int seq; /* Server sequence number */
|
||||||
void *server_tid; /* Server id for this thread */
|
void *server_tid; /* Server id for this thread */
|
||||||
struct _THDB *next; /* Global thread list */
|
void (*startup)(void); /* Thread startup routine */
|
||||||
|
struct _THDB *next; /* Global thread list */
|
||||||
} THDB;
|
} THDB;
|
||||||
|
|
||||||
/* The pseudo handle value returned by GetCurrentThread */
|
/* The pseudo handle value returned by GetCurrentThread */
|
||||||
|
@ -115,16 +116,13 @@ extern THDB *pCurrentThread;
|
||||||
|
|
||||||
|
|
||||||
/* scheduler/thread.c */
|
/* 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,
|
extern THDB *THREAD_Create( struct _PDB *pdb, DWORD flags,
|
||||||
DWORD stack_size, BOOL alloc_stack16,
|
DWORD stack_size, BOOL alloc_stack16,
|
||||||
LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa,
|
LPSECURITY_ATTRIBUTES sa, int *server_handle );
|
||||||
int *server_thandle, int *server_phandle,
|
|
||||||
LPTHREAD_START_ROUTINE start_addr, LPVOID param );
|
|
||||||
extern THDB *THREAD_Current(void);
|
extern THDB *THREAD_Current(void);
|
||||||
extern BOOL THREAD_IsWin16( THDB *thdb );
|
extern BOOL THREAD_IsWin16( THDB *thdb );
|
||||||
extern THDB *THREAD_IdToTHDB( DWORD id );
|
extern THDB *THREAD_IdToTHDB( DWORD id );
|
||||||
extern void THREAD_Start( THDB *thdb );
|
|
||||||
extern DWORD THREAD_TlsAlloc( THDB *thread );
|
extern DWORD THREAD_TlsAlloc( THDB *thread );
|
||||||
|
|
||||||
/* scheduler/sysdeps.c */
|
/* scheduler/sysdeps.c */
|
||||||
|
|
|
@ -983,15 +983,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine,
|
||||||
|
|
||||||
CloseHandle( hFile );
|
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;
|
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,
|
int CLIENT_InitServer(void)
|
||||||
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
|
||||||
int *thandle, int *phandle )
|
|
||||||
{
|
{
|
||||||
struct new_thread_request request;
|
|
||||||
struct new_thread_reply reply;
|
|
||||||
int fd[2];
|
int fd[2];
|
||||||
|
char buffer[16];
|
||||||
|
extern void create_initial_thread( int fd );
|
||||||
|
|
||||||
if (socketpair( AF_UNIX, SOCK_STREAM, 0, fd ) == -1)
|
if (socketpair( AF_UNIX, SOCK_STREAM, 0, fd ) == -1)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_TOO_MANY_OPEN_FILES ); /* FIXME */
|
perror("socketpair");
|
||||||
return -1;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
switch(fork())
|
||||||
request.pid = thdb->process->server_pid;
|
{
|
||||||
request.suspend = (thdb->flags & CREATE_SUSPENDED)? TRUE : FALSE;
|
case -1: /* error */
|
||||||
request.tinherit = (tsa && (tsa->nLength>=sizeof(*tsa)) && tsa->bInheritHandle);
|
perror("fork");
|
||||||
request.pinherit = (psa && (psa->nLength>=sizeof(*psa)) && psa->bInheritHandle);
|
exit(1);
|
||||||
CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) );
|
case 0: /* child */
|
||||||
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error;
|
close( fd[0] );
|
||||||
thdb->server_tid = reply.tid;
|
sprintf( buffer, "%d", fd[1] );
|
||||||
thdb->process->server_pid = reply.pid;
|
/*#define EXEC_SERVER*/
|
||||||
if (thdb->socket != -1) close( thdb->socket );
|
#ifdef EXEC_SERVER
|
||||||
thdb->socket = fd[0];
|
execlp( "wineserver", "wineserver", buffer, NULL );
|
||||||
thdb->seq = 0; /* reset the sequence number for the new fd */
|
execl( "/usr/local/bin/wineserver", "wineserver", buffer, NULL );
|
||||||
fcntl( fd[0], F_SETFD, 1 ); /* set close on exec flag */
|
execl( "./server/wineserver", "wineserver", buffer, NULL );
|
||||||
|
#endif
|
||||||
if (thandle) *thandle = reply.thandle;
|
create_initial_thread( fd[1] );
|
||||||
else if (reply.thandle != -1) CloseHandle( reply.thandle );
|
exit(0);
|
||||||
if (phandle) *phandle = reply.phandle;
|
default: /* parent */
|
||||||
else if (reply.phandle != -1) CloseHandle( reply.phandle );
|
close( fd[1] );
|
||||||
return 0;
|
break;
|
||||||
|
}
|
||||||
error:
|
return fd[0];
|
||||||
close( fd[0] );
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,16 +318,9 @@ int CLIENT_NewThread( THDB *thdb,
|
||||||
*/
|
*/
|
||||||
int CLIENT_InitThread(void)
|
int CLIENT_InitThread(void)
|
||||||
{
|
{
|
||||||
THDB *thdb = THREAD_Current();
|
|
||||||
struct init_thread_request init;
|
struct init_thread_request init;
|
||||||
int len = strlen( thdb->process->env_db->cmd_line );
|
|
||||||
|
|
||||||
init.unix_pid = getpid();
|
init.unix_pid = getpid();
|
||||||
len = MIN( len, MAX_MSG_LENGTH - sizeof(init) );
|
CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &init, sizeof(init) );
|
||||||
|
|
||||||
CLIENT_SendRequest( REQ_INIT_THREAD, -1, 2,
|
|
||||||
&init, sizeof(init),
|
|
||||||
thdb->process->env_db->cmd_line, len );
|
|
||||||
return CLIENT_WaitReply( NULL, NULL, 0 );
|
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
|
* PROCESS_FreePDB
|
||||||
*
|
*
|
||||||
|
@ -191,7 +240,6 @@ void PROCESS_FreePDB( PDB *pdb )
|
||||||
while (*pptr && (*pptr != pdb)) pptr = &(*pptr)->next;
|
while (*pptr && (*pptr != pdb)) pptr = &(*pptr)->next;
|
||||||
if (*pptr) *pptr = pdb->next;
|
if (*pptr) *pptr = pdb->next;
|
||||||
if (pdb->heap && (pdb->heap != pdb->system_heap)) HeapDestroy( pdb->heap );
|
if (pdb->heap && (pdb->heap != pdb->system_heap)) HeapDestroy( pdb->heap );
|
||||||
DeleteCriticalSection( &pdb->crit_section );
|
|
||||||
HeapFree( SystemHeap, 0, pdb );
|
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
|
* PROCESS_Init
|
||||||
*/
|
*/
|
||||||
BOOL PROCESS_Init(void)
|
BOOL PROCESS_Init(void)
|
||||||
{
|
{
|
||||||
THDB *thdb;
|
THDB *thdb;
|
||||||
|
int server_fd;
|
||||||
|
|
||||||
|
/* Start the server */
|
||||||
|
server_fd = CLIENT_InitServer();
|
||||||
|
|
||||||
/* Fill the initial process structure */
|
/* Fill the initial process structure */
|
||||||
initial_pdb.exit_code = 0x103; /* STILL_ACTIVE */
|
initial_pdb.exit_code = 0x103; /* STILL_ACTIVE */
|
||||||
|
@ -255,8 +292,8 @@ BOOL PROCESS_Init(void)
|
||||||
/* Initialize virtual memory management */
|
/* Initialize virtual memory management */
|
||||||
if (!VIRTUAL_Init()) return FALSE;
|
if (!VIRTUAL_Init()) return FALSE;
|
||||||
|
|
||||||
/* Create the initial thread structure */
|
/* Create the initial thread structure and socket pair */
|
||||||
if (!(thdb = THREAD_CreateInitialThread( &initial_pdb ))) return FALSE;
|
if (!(thdb = THREAD_CreateInitialThread( &initial_pdb, server_fd ))) return FALSE;
|
||||||
|
|
||||||
/* Remember TEB selector of initial process for emergency use */
|
/* Remember TEB selector of initial process for emergency use */
|
||||||
SYSLEVEL_EmergencyTeb = thdb->teb_sel;
|
SYSLEVEL_EmergencyTeb = thdb->teb_sel;
|
||||||
|
@ -270,15 +307,82 @@ BOOL PROCESS_Init(void)
|
||||||
|
|
||||||
/* Initialize the first thread */
|
/* Initialize the first thread */
|
||||||
if (CLIENT_InitThread()) return FALSE;
|
if (CLIENT_InitThread()) return FALSE;
|
||||||
if (!PROCESS_FinishCreatePDB( &initial_pdb )) return FALSE;
|
|
||||||
|
|
||||||
/* Create the SEGPTR heap */
|
/* Create the SEGPTR heap */
|
||||||
if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
|
if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
|
||||||
|
|
||||||
|
/* Initialize the first process critical section */
|
||||||
|
InitializeCriticalSection( &initial_pdb.crit_section );
|
||||||
|
|
||||||
return TRUE;
|
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
|
* PROCESS_Create
|
||||||
*
|
*
|
||||||
|
@ -291,7 +395,9 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
|
||||||
PROCESS_INFORMATION *info )
|
PROCESS_INFORMATION *info )
|
||||||
{
|
{
|
||||||
DWORD size, commit;
|
DWORD size, commit;
|
||||||
int server_thandle, server_phandle;
|
int server_thandle;
|
||||||
|
struct new_process_request req;
|
||||||
|
struct new_process_reply reply;
|
||||||
UINT cmdShow = 0;
|
UINT cmdShow = 0;
|
||||||
THDB *thdb = NULL;
|
THDB *thdb = NULL;
|
||||||
PDB *parent = PROCESS_Current();
|
PDB *parent = PROCESS_Current();
|
||||||
|
@ -299,7 +405,33 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
|
||||||
|
|
||||||
if (!pdb) return NULL;
|
if (!pdb) return NULL;
|
||||||
info->hThread = info->hProcess = INVALID_HANDLE_VALUE;
|
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 */
|
/* 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;
|
size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve;
|
||||||
else
|
else
|
||||||
size = 0;
|
size = 0;
|
||||||
if (!(thdb = THREAD_Create( pdb, 0L, size, hInstance == 0,
|
if (!(thdb = THREAD_Create( pdb, 0L, size, hInstance == 0, tsa, &server_thandle )))
|
||||||
tsa, psa, &server_thandle, &server_phandle,
|
|
||||||
NULL, NULL )))
|
|
||||||
goto error;
|
goto error;
|
||||||
info->hThread = server_thandle;
|
info->hThread = server_thandle;
|
||||||
info->hProcess = server_phandle;
|
|
||||||
info->dwProcessId = (DWORD)pdb->server_pid;
|
|
||||||
info->dwThreadId = (DWORD)thdb->server_tid;
|
info->dwThreadId = (DWORD)thdb->server_tid;
|
||||||
|
|
||||||
/* Duplicate the standard handles */
|
/* 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;
|
pdb->modref_list = PROCESS_Initial()->modref_list;
|
||||||
|
|
||||||
|
|
||||||
|
/* Start the task */
|
||||||
|
|
||||||
|
TASK_StartTask( pdb->task );
|
||||||
|
|
||||||
return pdb;
|
return pdb;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -381,12 +513,13 @@ void WINAPI ExitProcess( DWORD status )
|
||||||
TDB *pTask = (TDB *)GlobalLock16( pdb->task );
|
TDB *pTask = (TDB *)GlobalLock16( pdb->task );
|
||||||
if ( pTask ) pTask->nEvents++;
|
if ( pTask ) pTask->nEvents++;
|
||||||
|
|
||||||
|
MODULE_InitializeDLLs( 0, DLL_PROCESS_DETACH, NULL );
|
||||||
|
|
||||||
if ( pTask && pTask->thdb != THREAD_Current() )
|
if ( pTask && pTask->thdb != THREAD_Current() )
|
||||||
ExitThread( status );
|
TerminateProcess( GetCurrentProcess(), status );
|
||||||
|
|
||||||
/* FIXME: should kill all running threads of this process */
|
/* FIXME: should kill all running threads of this process */
|
||||||
pdb->exit_code = status;
|
pdb->exit_code = status;
|
||||||
FreeConsole();
|
|
||||||
|
|
||||||
__RESTORE_ES; /* Necessary for Pietrek's showseh example program */
|
__RESTORE_ES; /* Necessary for Pietrek's showseh example program */
|
||||||
TASK_KillCurrentTask( status );
|
TASK_KillCurrentTask( status );
|
||||||
|
|
|
@ -80,8 +80,14 @@ int *__h_errno_location()
|
||||||
*/
|
*/
|
||||||
static void SYSDEPS_StartThread( THDB *thdb )
|
static void SYSDEPS_StartThread( THDB *thdb )
|
||||||
{
|
{
|
||||||
SET_FS( thdb->teb_sel );
|
struct init_thread_request init;
|
||||||
THREAD_Start( thdb );
|
|
||||||
|
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 */
|
#endif /* USE_THREADS */
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -94,8 +95,7 @@ THDB *THREAD_IdToTHDB( DWORD id )
|
||||||
* Initialization of a newly created THDB.
|
* Initialization of a newly created THDB.
|
||||||
*/
|
*/
|
||||||
static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16,
|
static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16,
|
||||||
LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa,
|
LPSECURITY_ATTRIBUTES sa )
|
||||||
int *server_thandle, int *server_phandle )
|
|
||||||
{
|
{
|
||||||
DWORD old_prot;
|
DWORD old_prot;
|
||||||
|
|
||||||
|
@ -136,11 +136,6 @@ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16,
|
||||||
0x10000 - sizeof(STACK16FRAME) );
|
0x10000 - sizeof(STACK16FRAME) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the thread socket */
|
|
||||||
|
|
||||||
if (CLIENT_NewThread( thdb, tsa, psa, server_thandle, server_phandle ))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* Create the thread event */
|
/* Create the thread event */
|
||||||
|
|
||||||
if (!(thdb->event = CreateEventA( NULL, FALSE, FALSE, NULL ))) goto error;
|
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;
|
return TRUE;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (thdb->socket != -1) close( thdb->socket );
|
|
||||||
if (thdb->event) CloseHandle( thdb->event );
|
if (thdb->event) CloseHandle( thdb->event );
|
||||||
if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
|
if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
|
||||||
if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE );
|
if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE );
|
||||||
|
@ -189,51 +183,16 @@ void THREAD_FreeTHDB( THDB *thdb )
|
||||||
*
|
*
|
||||||
* Create the initial thread.
|
* 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.process = pdb;
|
||||||
initial_thdb.teb.except = (void *)-1;
|
initial_thdb.teb.except = (void *)-1;
|
||||||
initial_thdb.teb.self = &initial_thdb.teb;
|
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.tls_ptr = initial_thdb.tls_array;
|
||||||
initial_thdb.teb.process = pdb;
|
initial_thdb.teb.process = pdb;
|
||||||
initial_thdb.exit_code = 0x103; /* STILL_ACTIVE */
|
initial_thdb.exit_code = 0x103; /* STILL_ACTIVE */
|
||||||
initial_thdb.socket = -1;
|
initial_thdb.socket = server_fd;
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate the TEB selector (%fs register) */
|
/* Allocate the TEB selector (%fs register) */
|
||||||
|
|
||||||
|
@ -248,8 +207,7 @@ THDB *THREAD_CreateInitialThread( PDB *pdb )
|
||||||
|
|
||||||
/* Now proceed with normal initialization */
|
/* Now proceed with normal initialization */
|
||||||
|
|
||||||
if (!THREAD_InitTHDB( &initial_thdb, 0, TRUE,
|
if (!THREAD_InitTHDB( &initial_thdb, 0, TRUE, NULL )) return NULL;
|
||||||
NULL, NULL, NULL, NULL )) return NULL;
|
|
||||||
return &initial_thdb;
|
return &initial_thdb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,10 +216,12 @@ THDB *THREAD_CreateInitialThread( PDB *pdb )
|
||||||
* THREAD_Create
|
* THREAD_Create
|
||||||
*/
|
*/
|
||||||
THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
|
THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
|
||||||
LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa,
|
LPSECURITY_ATTRIBUTES sa, int *server_handle )
|
||||||
int *server_thandle, int *server_phandle,
|
|
||||||
LPTHREAD_START_ROUTINE start_addr, LPVOID param )
|
|
||||||
{
|
{
|
||||||
|
struct new_thread_request request;
|
||||||
|
struct new_thread_reply reply = { NULL, -1 };
|
||||||
|
int fd[2];
|
||||||
|
|
||||||
THDB *thdb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(THDB) );
|
THDB *thdb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(THDB) );
|
||||||
if (!thdb) return NULL;
|
if (!thdb) return NULL;
|
||||||
thdb->process = pdb;
|
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->teb.process = pdb;
|
||||||
thdb->exit_code = 0x103; /* STILL_ACTIVE */
|
thdb->exit_code = 0x103; /* STILL_ACTIVE */
|
||||||
thdb->flags = flags;
|
thdb->flags = flags;
|
||||||
thdb->entry_point = start_addr;
|
|
||||||
thdb->entry_arg = param;
|
|
||||||
thdb->socket = -1;
|
thdb->socket = -1;
|
||||||
|
|
||||||
/* Allocate the TEB selector (%fs register) */
|
/* 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 );
|
TRUE, FALSE );
|
||||||
if (!thdb->teb_sel) goto error;
|
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 */
|
/* Do the rest of the initialization */
|
||||||
|
|
||||||
if (!THREAD_InitTHDB( thdb, stack_size, alloc_stack16,
|
if (!THREAD_InitTHDB( thdb, stack_size, alloc_stack16, sa )) goto error;
|
||||||
tsa, psa, server_thandle, server_phandle ))
|
|
||||||
goto error;
|
|
||||||
thdb->next = THREAD_First;
|
thdb->next = THREAD_First;
|
||||||
THREAD_First = thdb;
|
THREAD_First = thdb;
|
||||||
PE_InitTls( thdb );
|
PE_InitTls( thdb );
|
||||||
return thdb;
|
return thdb;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
if (reply.handle != -1) CloseHandle( reply.handle );
|
||||||
if (thdb->teb_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 );
|
if (thdb->teb_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 );
|
||||||
HeapFree( SystemHeap, 0, thdb );
|
HeapFree( SystemHeap, 0, thdb );
|
||||||
|
if (thdb->socket != -1) close( thdb->socket );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,11 +283,10 @@ error:
|
||||||
*
|
*
|
||||||
* Start execution of a newly created thread. Does not return.
|
* 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;
|
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)thdb->entry_point;
|
||||||
assert( THREAD_Current() == thdb );
|
|
||||||
CLIENT_InitThread();
|
|
||||||
MODULE_InitializeDLLs( 0, DLL_THREAD_ATTACH, NULL );
|
MODULE_InitializeDLLs( 0, DLL_THREAD_ATTACH, NULL );
|
||||||
ExitThread( func( thdb->entry_arg ) );
|
ExitThread( func( thdb->entry_arg ) );
|
||||||
}
|
}
|
||||||
|
@ -323,9 +300,11 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
|
||||||
DWORD flags, LPDWORD id )
|
DWORD flags, LPDWORD id )
|
||||||
{
|
{
|
||||||
int handle = -1;
|
int handle = -1;
|
||||||
THDB *thread = THREAD_Create( PROCESS_Current(), flags, stack,
|
THDB *thread = THREAD_Create( PROCESS_Current(), flags, stack, TRUE, sa, &handle );
|
||||||
TRUE, sa, NULL, &handle, NULL, start, param );
|
|
||||||
if (!thread) return INVALID_HANDLE_VALUE;
|
if (!thread) return INVALID_HANDLE_VALUE;
|
||||||
|
thread->entry_point = start;
|
||||||
|
thread->entry_arg = param;
|
||||||
|
thread->startup = THREAD_Start;
|
||||||
if (SYSDEPS_SpawnThread( thread ) == -1)
|
if (SYSDEPS_SpawnThread( thread ) == -1)
|
||||||
{
|
{
|
||||||
CloseHandle( handle );
|
CloseHandle( handle );
|
||||||
|
|
Loading…
Reference in a new issue