ntdll: Move the rest of the thread creation code to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f4efea2233
commit
ca3ca7b046
|
@ -348,90 +348,24 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
|
||||||
PRTL_THREAD_START_ROUTINE start, void *param,
|
PRTL_THREAD_START_ROUTINE start, void *param,
|
||||||
HANDLE *handle_ptr, CLIENT_ID *id )
|
HANDLE *handle_ptr, CLIENT_ID *id )
|
||||||
{
|
{
|
||||||
HANDLE handle = 0, actctx = 0;
|
ULONG flags = suspended ? THREAD_CREATE_FLAGS_CREATE_SUSPENDED : 0;
|
||||||
DWORD tid = 0;
|
HANDLE handle;
|
||||||
int request_pipe[2];
|
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
data_size_t len = 0;
|
CLIENT_ID client_id;
|
||||||
struct object_attributes *objattr = NULL;
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
|
||||||
if (process != NtCurrentProcess())
|
InitializeObjectAttributes( &attr, NULL, 0, NULL, descr );
|
||||||
|
|
||||||
|
status = unix_funcs->create_thread( &handle, THREAD_ALL_ACCESS, &attr, process,
|
||||||
|
start, param, call_thread_entry_point, flags,
|
||||||
|
stack_commit, stack_reserve, &client_id );
|
||||||
|
if (!status)
|
||||||
{
|
{
|
||||||
apc_call_t call;
|
if (id) *id = client_id;
|
||||||
apc_result_t result;
|
if (handle_ptr) *handle_ptr = handle;
|
||||||
|
else NtClose( handle );
|
||||||
memset( &call, 0, sizeof(call) );
|
|
||||||
|
|
||||||
call.create_thread.type = APC_CREATE_THREAD;
|
|
||||||
call.create_thread.func = wine_server_client_ptr( start );
|
|
||||||
call.create_thread.arg = wine_server_client_ptr( param );
|
|
||||||
call.create_thread.reserve = stack_reserve;
|
|
||||||
call.create_thread.commit = stack_commit;
|
|
||||||
call.create_thread.suspend = suspended;
|
|
||||||
status = unix_funcs->server_queue_process_apc( process, &call, &result );
|
|
||||||
if (status != STATUS_SUCCESS) return status;
|
|
||||||
|
|
||||||
if (result.create_thread.status == STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
if (id) id->UniqueThread = ULongToHandle(result.create_thread.tid);
|
|
||||||
if (handle_ptr) *handle_ptr = wine_server_ptr_handle( result.create_thread.handle );
|
|
||||||
else NtClose( wine_server_ptr_handle( result.create_thread.handle ));
|
|
||||||
}
|
|
||||||
return result.create_thread.status;
|
|
||||||
}
|
}
|
||||||
|
return status;
|
||||||
if (descr)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES thread_attr;
|
|
||||||
InitializeObjectAttributes( &thread_attr, NULL, 0, NULL, descr );
|
|
||||||
if ((status = alloc_object_attributes( &thread_attr, &objattr, &len ))) return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unix_funcs->server_pipe( request_pipe ) == -1)
|
|
||||||
{
|
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
|
||||||
return STATUS_TOO_MANY_OPENED_FILES;
|
|
||||||
}
|
|
||||||
wine_server_send_fd( request_pipe[0] );
|
|
||||||
|
|
||||||
SERVER_START_REQ( new_thread )
|
|
||||||
{
|
|
||||||
req->process = wine_server_obj_handle( process );
|
|
||||||
req->access = THREAD_ALL_ACCESS;
|
|
||||||
req->suspend = suspended;
|
|
||||||
req->request_fd = request_pipe[0];
|
|
||||||
wine_server_add_data( req, objattr, len );
|
|
||||||
if (!(status = wine_server_call( req )))
|
|
||||||
{
|
|
||||||
handle = wine_server_ptr_handle( reply->handle );
|
|
||||||
tid = reply->tid;
|
|
||||||
}
|
|
||||||
close( request_pipe[0] );
|
|
||||||
}
|
|
||||||
SERVER_END_REQ;
|
|
||||||
|
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
|
||||||
if (status)
|
|
||||||
{
|
|
||||||
close( request_pipe[1] );
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlGetActiveActivationContext( &actctx );
|
|
||||||
|
|
||||||
status = unix_funcs->create_thread( stack_reserve, stack_commit, actctx, tid, request_pipe[1],
|
|
||||||
start, param, call_thread_entry_point );
|
|
||||||
if (status)
|
|
||||||
{
|
|
||||||
if (actctx) RtlReleaseActivationContext( actctx );
|
|
||||||
NtClose( handle );
|
|
||||||
close( request_pipe[1] );
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
if (id) id->UniqueThread = ULongToHandle(tid);
|
|
||||||
if (handle_ptr) *handle_ptr = handle;
|
|
||||||
else NtClose( handle );
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1078,7 +1078,6 @@ static struct unix_funcs unix_funcs =
|
||||||
server_fd_to_handle,
|
server_fd_to_handle,
|
||||||
server_handle_to_fd,
|
server_handle_to_fd,
|
||||||
server_release_fd,
|
server_release_fd,
|
||||||
server_pipe,
|
|
||||||
server_init_process_done,
|
server_init_process_done,
|
||||||
__wine_dbg_get_channel_flags,
|
__wine_dbg_get_channel_flags,
|
||||||
__wine_dbg_strdup,
|
__wine_dbg_strdup,
|
||||||
|
|
|
@ -1100,7 +1100,7 @@ void CDECL server_release_fd( HANDLE handle, int unix_fd )
|
||||||
*
|
*
|
||||||
* Create a pipe for communicating with the server.
|
* Create a pipe for communicating with the server.
|
||||||
*/
|
*/
|
||||||
int CDECL server_pipe( int fd[2] )
|
int server_pipe( int fd[2] )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
#ifdef HAVE_PIPE2
|
#ifdef HAVE_PIPE2
|
||||||
|
|
|
@ -72,8 +72,8 @@ HANDLE keyed_event = 0;
|
||||||
|
|
||||||
|
|
||||||
/* create a struct security_descriptor and contained information in one contiguous piece of memory */
|
/* create a struct security_descriptor and contained information in one contiguous piece of memory */
|
||||||
static NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
|
NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
|
||||||
data_size_t *ret_len )
|
data_size_t *ret_len )
|
||||||
{
|
{
|
||||||
unsigned int len = sizeof(**ret);
|
unsigned int len = sizeof(**ret);
|
||||||
PSID owner = NULL, group = NULL;
|
PSID owner = NULL, group = NULL;
|
||||||
|
|
|
@ -157,19 +157,84 @@ static void start_thread( TEB *teb )
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* create_thread
|
* create_thread
|
||||||
*/
|
*/
|
||||||
NTSTATUS CDECL create_thread( SIZE_T stack_reserve, SIZE_T stack_commit, HANDLE actctx, DWORD tid,
|
NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
||||||
int request_fd, PRTL_THREAD_START_ROUTINE start, void *param, void *relay )
|
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param, void *relay,
|
||||||
|
ULONG flags, SIZE_T stack_commit, SIZE_T stack_reserve,
|
||||||
|
CLIENT_ID *id )
|
||||||
{
|
{
|
||||||
sigset_t sigset;
|
sigset_t sigset;
|
||||||
pthread_t pthread_id;
|
pthread_t pthread_id;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t pthread_attr;
|
||||||
|
data_size_t len;
|
||||||
|
struct object_attributes *objattr;
|
||||||
struct ntdll_thread_data *thread_data;
|
struct ntdll_thread_data *thread_data;
|
||||||
struct startup_info *info;
|
struct startup_info *info;
|
||||||
|
DWORD tid = 0;
|
||||||
|
int request_pipe[2];
|
||||||
SIZE_T extra_stack = PTHREAD_STACK_MIN;
|
SIZE_T extra_stack = PTHREAD_STACK_MIN;
|
||||||
|
HANDLE actctx;
|
||||||
TEB *teb;
|
TEB *teb;
|
||||||
INITIAL_TEB stack;
|
INITIAL_TEB stack;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (process != NtCurrentProcess())
|
||||||
|
{
|
||||||
|
apc_call_t call;
|
||||||
|
apc_result_t result;
|
||||||
|
|
||||||
|
memset( &call, 0, sizeof(call) );
|
||||||
|
|
||||||
|
call.create_thread.type = APC_CREATE_THREAD;
|
||||||
|
call.create_thread.func = wine_server_client_ptr( start );
|
||||||
|
call.create_thread.arg = wine_server_client_ptr( param );
|
||||||
|
call.create_thread.reserve = stack_reserve;
|
||||||
|
call.create_thread.commit = stack_commit;
|
||||||
|
call.create_thread.suspend = flags & THREAD_CREATE_FLAGS_CREATE_SUSPENDED;
|
||||||
|
status = server_queue_process_apc( process, &call, &result );
|
||||||
|
if (status != STATUS_SUCCESS) return status;
|
||||||
|
|
||||||
|
if (result.create_thread.status == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
if (id) id->UniqueThread = ULongToHandle( result.create_thread.tid );
|
||||||
|
*handle = wine_server_ptr_handle( result.create_thread.handle );
|
||||||
|
}
|
||||||
|
return result.create_thread.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status;
|
||||||
|
|
||||||
|
if (server_pipe( request_pipe ) == -1)
|
||||||
|
{
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
||||||
|
return STATUS_TOO_MANY_OPENED_FILES;
|
||||||
|
}
|
||||||
|
server_send_fd( request_pipe[0] );
|
||||||
|
|
||||||
|
SERVER_START_REQ( new_thread )
|
||||||
|
{
|
||||||
|
req->process = wine_server_obj_handle( process );
|
||||||
|
req->access = access;
|
||||||
|
req->suspend = flags & THREAD_CREATE_FLAGS_CREATE_SUSPENDED;
|
||||||
|
req->request_fd = request_pipe[0];
|
||||||
|
wine_server_add_data( req, objattr, len );
|
||||||
|
if (!(status = wine_server_call( req )))
|
||||||
|
{
|
||||||
|
*handle = wine_server_ptr_handle( reply->handle );
|
||||||
|
tid = reply->tid;
|
||||||
|
}
|
||||||
|
close( request_pipe[0] );
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
close( request_pipe[1] );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlGetActiveActivationContext( &actctx );
|
||||||
|
|
||||||
pthread_sigmask( SIG_BLOCK, &server_block_set, &sigset );
|
pthread_sigmask( SIG_BLOCK, &server_block_set, &sigset );
|
||||||
|
|
||||||
if ((status = virtual_alloc_teb( &teb ))) goto done;
|
if ((status = virtual_alloc_teb( &teb ))) goto done;
|
||||||
|
@ -182,6 +247,7 @@ NTSTATUS CDECL create_thread( SIZE_T stack_reserve, SIZE_T stack_commit, HANDLE
|
||||||
|
|
||||||
teb->ClientId.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
|
teb->ClientId.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
|
||||||
teb->ClientId.UniqueThread = ULongToHandle( tid );
|
teb->ClientId.UniqueThread = ULongToHandle( tid );
|
||||||
|
if (id) *id = teb->ClientId;
|
||||||
|
|
||||||
info = (struct startup_info *)(teb + 1);
|
info = (struct startup_info *)(teb + 1);
|
||||||
info->entry = start;
|
info->entry = start;
|
||||||
|
@ -194,27 +260,32 @@ NTSTATUS CDECL create_thread( SIZE_T stack_reserve, SIZE_T stack_commit, HANDLE
|
||||||
teb->DeallocationStack = stack.DeallocationStack;
|
teb->DeallocationStack = stack.DeallocationStack;
|
||||||
|
|
||||||
thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
||||||
thread_data->request_fd = request_fd;
|
thread_data->request_fd = request_pipe[1];
|
||||||
thread_data->reply_fd = -1;
|
thread_data->reply_fd = -1;
|
||||||
thread_data->wait_fd[0] = -1;
|
thread_data->wait_fd[0] = -1;
|
||||||
thread_data->wait_fd[1] = -1;
|
thread_data->wait_fd[1] = -1;
|
||||||
thread_data->start_stack = (char *)teb->Tib.StackBase;
|
thread_data->start_stack = (char *)teb->Tib.StackBase;
|
||||||
|
|
||||||
pthread_attr_init( &attr );
|
pthread_attr_init( &pthread_attr );
|
||||||
pthread_attr_setstack( &attr, teb->DeallocationStack,
|
pthread_attr_setstack( &pthread_attr, teb->DeallocationStack,
|
||||||
(char *)teb->Tib.StackBase + extra_stack - (char *)teb->DeallocationStack );
|
(char *)teb->Tib.StackBase + extra_stack - (char *)teb->DeallocationStack );
|
||||||
pthread_attr_setguardsize( &attr, 0 );
|
pthread_attr_setguardsize( &pthread_attr, 0 );
|
||||||
pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); /* force creating a kernel thread */
|
pthread_attr_setscope( &pthread_attr, PTHREAD_SCOPE_SYSTEM ); /* force creating a kernel thread */
|
||||||
InterlockedIncrement( nb_threads );
|
InterlockedIncrement( nb_threads );
|
||||||
if (pthread_create( &pthread_id, &attr, (void * (*)(void *))start_thread, teb ))
|
if (pthread_create( &pthread_id, &pthread_attr, (void * (*)(void *))start_thread, teb ))
|
||||||
{
|
{
|
||||||
InterlockedDecrement( nb_threads );
|
InterlockedDecrement( nb_threads );
|
||||||
virtual_free_teb( teb );
|
virtual_free_teb( teb );
|
||||||
status = STATUS_NO_MEMORY;
|
status = STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
pthread_attr_destroy( &attr );
|
pthread_attr_destroy( &pthread_attr );
|
||||||
|
|
||||||
done:
|
done:
|
||||||
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
|
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
|
||||||
|
if (!status) return STATUS_SUCCESS;
|
||||||
|
NtClose( *handle );
|
||||||
|
RtlReleaseActivationContext( actctx );
|
||||||
|
close( request_pipe[1] );
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,14 +93,14 @@ extern NTSTATUS CDECL server_fd_to_handle( int fd, unsigned int access, unsigned
|
||||||
extern NTSTATUS CDECL server_handle_to_fd( HANDLE handle, unsigned int access, int *unix_fd,
|
extern NTSTATUS CDECL server_handle_to_fd( HANDLE handle, unsigned int access, int *unix_fd,
|
||||||
unsigned int *options ) DECLSPEC_HIDDEN;
|
unsigned int *options ) DECLSPEC_HIDDEN;
|
||||||
extern void CDECL server_release_fd( HANDLE handle, int unix_fd ) DECLSPEC_HIDDEN;
|
extern void CDECL server_release_fd( HANDLE handle, int unix_fd ) DECLSPEC_HIDDEN;
|
||||||
extern int CDECL server_pipe( int fd[2] ) DECLSPEC_HIDDEN;
|
|
||||||
extern void CDECL server_init_process_done(void) DECLSPEC_HIDDEN;
|
extern void CDECL server_init_process_done(void) DECLSPEC_HIDDEN;
|
||||||
extern TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size,
|
extern TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size,
|
||||||
BOOL *suspend, unsigned int *cpus, BOOL *wow64,
|
BOOL *suspend, unsigned int *cpus, BOOL *wow64,
|
||||||
timeout_t *start_time ) DECLSPEC_HIDDEN;
|
timeout_t *start_time ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS CDECL create_thread( SIZE_T stack_reserve, SIZE_T stack_commit, HANDLE actctx, DWORD tid,
|
extern NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
||||||
int request_fd, PRTL_THREAD_START_ROUTINE start,
|
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param, void *relay,
|
||||||
void *param, void *relay ) DECLSPEC_HIDDEN;
|
ULONG flags, SIZE_T stack_commit, SIZE_T stack_reserve,
|
||||||
|
CLIENT_ID *id ) DECLSPEC_HIDDEN;
|
||||||
extern void CDECL DECLSPEC_NORETURN start_process( PRTL_THREAD_START_ROUTINE entry, BOOL suspend, void *relay ) DECLSPEC_HIDDEN;
|
extern void CDECL DECLSPEC_NORETURN start_process( PRTL_THREAD_START_ROUTINE entry, BOOL suspend, void *relay ) DECLSPEC_HIDDEN;
|
||||||
extern void CDECL DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;
|
extern void CDECL DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;
|
||||||
extern void CDECL DECLSPEC_NORETURN exit_thread( int status ) DECLSPEC_HIDDEN;
|
extern void CDECL DECLSPEC_NORETURN exit_thread( int status ) DECLSPEC_HIDDEN;
|
||||||
|
@ -124,12 +124,15 @@ extern void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset
|
||||||
extern void start_server( BOOL debug ) DECLSPEC_HIDDEN;
|
extern void start_server( BOOL debug ) DECLSPEC_HIDDEN;
|
||||||
extern void server_init_process(void) DECLSPEC_HIDDEN;
|
extern void server_init_process(void) DECLSPEC_HIDDEN;
|
||||||
extern size_t server_init_thread( void *entry_point, BOOL *suspend ) DECLSPEC_HIDDEN;
|
extern size_t server_init_thread( void *entry_point, BOOL *suspend ) DECLSPEC_HIDDEN;
|
||||||
|
extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) DECLSPEC_HIDDEN;
|
extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) DECLSPEC_HIDDEN;
|
extern NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) DECLSPEC_HIDDEN;
|
||||||
extern void wait_suspend( CONTEXT *context ) DECLSPEC_HIDDEN;
|
extern void wait_suspend( CONTEXT *context ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self ) DECLSPEC_HIDDEN;
|
extern NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int flags, BOOL *self ) DECLSPEC_HIDDEN;
|
extern NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int flags, BOOL *self ) DECLSPEC_HIDDEN;
|
||||||
|
extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
|
||||||
|
data_size_t *ret_len ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern void virtual_init(void) DECLSPEC_HIDDEN;
|
extern void virtual_init(void) DECLSPEC_HIDDEN;
|
||||||
extern TEB *virtual_alloc_first_teb(void) DECLSPEC_HIDDEN;
|
extern TEB *virtual_alloc_first_teb(void) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
||||||
struct msghdr;
|
struct msghdr;
|
||||||
|
|
||||||
/* increment this when you change the function table */
|
/* increment this when you change the function table */
|
||||||
#define NTDLL_UNIXLIB_VERSION 27
|
#define NTDLL_UNIXLIB_VERSION 28
|
||||||
|
|
||||||
struct unix_funcs
|
struct unix_funcs
|
||||||
{
|
{
|
||||||
|
@ -166,9 +166,10 @@ struct unix_funcs
|
||||||
/* thread/process functions */
|
/* thread/process functions */
|
||||||
TEB * (CDECL *init_threading)( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size,
|
TEB * (CDECL *init_threading)( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size,
|
||||||
BOOL *suspend, unsigned int *cpus, BOOL *wow64, timeout_t *start_time );
|
BOOL *suspend, unsigned int *cpus, BOOL *wow64, timeout_t *start_time );
|
||||||
NTSTATUS (CDECL *create_thread)( SIZE_T stack_reserve, SIZE_T stack_commit, HANDLE actctx,
|
NTSTATUS (CDECL *create_thread)( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
||||||
DWORD tid, int request_fd, PRTL_THREAD_START_ROUTINE start,
|
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param, void *relay,
|
||||||
void *param, void *relay );
|
ULONG flags, SIZE_T stack_commit, SIZE_T stack_reserve,
|
||||||
|
CLIENT_ID *id );
|
||||||
void (CDECL *start_process)( PRTL_THREAD_START_ROUTINE entry, BOOL suspend, void *relay );
|
void (CDECL *start_process)( PRTL_THREAD_START_ROUTINE entry, BOOL suspend, void *relay );
|
||||||
void (CDECL *abort_thread)( int status );
|
void (CDECL *abort_thread)( int status );
|
||||||
void (CDECL *exit_thread)( int status );
|
void (CDECL *exit_thread)( int status );
|
||||||
|
@ -191,7 +192,6 @@ struct unix_funcs
|
||||||
NTSTATUS (CDECL *server_handle_to_fd)( HANDLE handle, unsigned int access, int *unix_fd,
|
NTSTATUS (CDECL *server_handle_to_fd)( HANDLE handle, unsigned int access, int *unix_fd,
|
||||||
unsigned int *options );
|
unsigned int *options );
|
||||||
void (CDECL *server_release_fd)( HANDLE handle, int unix_fd );
|
void (CDECL *server_release_fd)( HANDLE handle, int unix_fd );
|
||||||
int (CDECL *server_pipe)( int fd[2] );
|
|
||||||
void (CDECL *server_init_process_done)(void);
|
void (CDECL *server_init_process_done)(void);
|
||||||
|
|
||||||
/* debugging functions */
|
/* debugging functions */
|
||||||
|
|
Loading…
Reference in New Issue