Added new_process and init_process request.

Split out process creation from thread creation.
Changed server initialisation to ensure that we always have a current
thread.
This commit is contained in:
Alexandre Julliard 1999-03-21 19:23:54 +00:00
parent 4f278bdac1
commit f692d44607
11 changed files with 266 additions and 165 deletions

View File

@ -40,20 +40,34 @@ struct cmsg_fd
/* which case it isn't necessary to define a structure. */
/* Create a new process from the context of the parent */
struct new_process_request
{
int inherit; /* inherit flag */
int inherit_all; /* inherit all handles from parent */
int start_flags; /* flags from startup info */
int hstdin; /* handle for stdin */
int hstdout; /* handle for stdout */
int hstderr; /* handle for stderr */
};
struct new_process_reply
{
void* pid; /* process id */
int handle; /* process handle (in the current process) */
};
/* Create a new thread from the context of the parent */
struct new_thread_request
{
void* pid; /* process id for the new thread (or 0 if none yet) */
void* pid; /* process id for the new thread */
int suspend; /* new thread should be suspended on creation */
int tinherit; /* inherit flag for thread handle */
int pinherit; /* inherit flag for process handle */
int inherit; /* inherit flag */
};
struct new_thread_reply
{
void* tid; /* thread id */
int thandle; /* thread handle (in the current process) */
void* pid; /* process id (created if necessary) */
int phandle; /* process handle (in the current process) */
int handle; /* thread handle (in the current process) */
};
@ -64,11 +78,24 @@ struct set_debug_request
};
/* Initialize a process; called from the new process context */
struct init_process_request
{
int dummy;
};
struct init_process_reply
{
int start_flags; /* flags from startup info */
int hstdin; /* handle for stdin */
int hstdout; /* handle for stdout */
int hstderr; /* handle for stderr */
};
/* Initialize a thread; called from the child after fork()/clone() */
struct init_thread_request
{
int unix_pid; /* Unix pid of new thread */
char cmd_line[0]; /* Thread command line */
};
@ -122,7 +149,7 @@ struct get_thread_info_request
};
struct get_thread_info_reply
{
void* pid; /* server thread id */
void* tid; /* server thread id */
int exit_code; /* thread exit code */
int priority; /* thread priority level */
};
@ -657,11 +684,9 @@ extern void CLIENT_SendRequest( enum request req, int pass_fd,
extern unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
int n, ... /* arg_1, len_1, etc. */ );
extern unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd );
extern int CLIENT_InitServer(void);
struct _THDB;
extern int CLIENT_NewThread( struct _THDB *thdb,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
int *thandle, int *phandle );
extern int CLIENT_SetDebug( int level );
extern int CLIENT_InitThread(void);
#endif /* __WINE_SERVER__ */

View File

@ -112,10 +112,8 @@ extern void select_loop(void);
/* socket functions */
extern void server_init( int fd );
extern int add_client( int client_fd, struct thread *self );
extern void remove_client( int client_fd, int exit_code );
extern int get_initial_client_fd(void);
extern void set_timeout( int client_fd, struct timeval *when );
extern int send_reply_v( int client_fd, int type, int pass_fd,
struct iovec *vec, int veclen );

View File

@ -27,9 +27,11 @@ struct process_snapshot
/* process functions */
extern struct process *create_process(void);
extern struct process *create_initial_process(void);
extern struct process *create_process( struct new_process_request *req );
extern struct process *get_process_from_id( void *id );
extern struct process *get_process_from_handle( int handle, unsigned int access );
extern int get_process_init_info( struct process *process, struct init_process_reply *reply );
extern void add_process_thread( struct process *process,
struct thread *thread );
extern void remove_process_thread( struct process *process,

View File

@ -5,8 +5,10 @@
enum request
{
REQ_NEW_PROCESS,
REQ_NEW_THREAD,
REQ_SET_DEBUG,
REQ_INIT_PROCESS,
REQ_INIT_THREAD,
REQ_TERMINATE_PROCESS,
REQ_TERMINATE_THREAD,
@ -65,8 +67,10 @@ enum request
#define DECL_HANDLER(name) \
static void req_##name( struct name##_request *req, void *data, int len, int fd )
DECL_HANDLER(new_process);
DECL_HANDLER(new_thread);
DECL_HANDLER(set_debug);
DECL_HANDLER(init_process);
DECL_HANDLER(init_thread);
DECL_HANDLER(terminate_process);
DECL_HANDLER(terminate_thread);
@ -122,8 +126,10 @@ static const struct handler {
void (*handler)();
unsigned int min_size;
} req_handlers[REQ_NB_REQUESTS] = {
{ (void(*)())req_new_process, sizeof(struct new_process_request) },
{ (void(*)())req_new_thread, sizeof(struct new_thread_request) },
{ (void(*)())req_set_debug, sizeof(struct set_debug_request) },
{ (void(*)())req_init_process, sizeof(struct init_process_request) },
{ (void(*)())req_init_thread, sizeof(struct init_thread_request) },
{ (void(*)())req_terminate_process, sizeof(struct terminate_process_request) },
{ (void(*)())req_terminate_thread, sizeof(struct terminate_thread_request) },

View File

@ -43,16 +43,14 @@ struct thread
int affinity; /* affinity mask */
int suspend; /* suspend count */
enum request last_req; /* last request received (for debugging) */
char *name;
};
extern struct thread *current;
/* thread functions */
extern struct thread *create_thread( int fd, void *pid, int suspend,
int thread_inherit, int process_inherit,
int *thread_handle, int *process_handle );
extern void create_initial_thread( int fd );
extern struct thread *create_thread( int fd, void *pid, int suspend, int inherit, int *handle );
extern struct thread *get_thread_from_id( void *id );
extern struct thread *get_thread_from_handle( int handle, unsigned int access );
extern void get_thread_info( struct thread *thread,

View File

@ -12,6 +12,7 @@
#include "server.h"
#include "server/object.h"
#include "server/thread.h"
int main( int argc, char *argv[] )
{
@ -26,8 +27,7 @@ int main( int argc, char *argv[] )
debug_level = 1;
if (debug_level) fprintf( stderr, "Server: starting (pid=%d)\n", getpid() );
server_init( fd );
select_loop();
create_initial_thread( fd );
if (debug_level) fprintf( stderr, "Server: exiting (pid=%d)\n", getpid() );
exit(0);

View File

@ -38,8 +38,7 @@ struct handle_entry
unsigned int access;
};
/* process structure; not much for now... */
/* process structure */
struct process
{
struct object obj; /* object header */
@ -57,10 +56,12 @@ struct process
int affinity; /* process affinity mask */
struct object *console_in; /* console input */
struct object *console_out; /* console output */
struct new_process_request *info; /* startup info (freed after startup) */
};
static struct process *first_process;
static struct process *initial_process;
static struct process initial_process;
static struct process *first_process = &initial_process;
static int running_processes;
#define MIN_HANDLE_ENTRIES 32
@ -87,21 +88,12 @@ static const struct object_ops process_ops =
process_destroy
};
/* create a new process */
struct process *create_process(void)
/* initialization of a process structure */
static void init_process( struct process *process )
{
struct process *process, *parent;
if (!(process = mem_alloc( sizeof(*process) ))) return NULL;
parent = current ? current->process : NULL;
if (!copy_handle_table( process, parent ))
{
free( process );
return NULL;
}
init_object( &process->obj, &process_ops, NULL );
process->next = first_process;
process->next = NULL;
process->prev = NULL;
process->thread_list = NULL;
process->exit_code = 0x103; /* STILL_ACTIVE */
@ -110,24 +102,59 @@ struct process *create_process(void)
process->affinity = 1;
process->console_in = NULL;
process->console_out = NULL;
if (parent)
{
if (parent->console_in) process->console_in = grab_object( parent->console_in );
if (parent->console_out) process->console_out = grab_object( parent->console_out );
}
if (first_process) first_process->prev = process;
first_process = process;
if (!initial_process)
{
initial_process = process;
grab_object( initial_process ); /* so that we never free it */
}
process->info = NULL;
gettimeofday( &process->start_time, NULL );
/* alloc a handle for the process itself */
alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 );
}
/* create the initial process */
struct process *create_initial_process(void)
{
copy_handle_table( &initial_process, NULL );
init_process( &initial_process );
grab_object( &initial_process ); /* so that we never free it */
return &initial_process;
}
/* create a new process */
struct process *create_process( struct new_process_request *req )
{
struct process *process = NULL;
struct process *parent = current->process;
if (!(process = mem_alloc( sizeof(*process) ))) return NULL;
if (!copy_handle_table( process, req->inherit_all ? parent : NULL ))
{
free( process );
return NULL;
}
init_process( process );
if (parent->console_in) process->console_in = grab_object( parent->console_in );
if (parent->console_out) process->console_out = grab_object( parent->console_out );
if (!(process->info = mem_alloc( sizeof(*process->info) ))) goto error;
memcpy( process->info, req, sizeof(*req) );
if (!req->inherit_all && !(req->start_flags & STARTF_USESTDHANDLES))
{
process->info->hstdin = duplicate_handle( parent, req->hstdin, process,
0, TRUE, DUPLICATE_SAME_ACCESS );
process->info->hstdout = duplicate_handle( parent, req->hstdout, process,
0, TRUE, DUPLICATE_SAME_ACCESS );
process->info->hstderr = duplicate_handle( parent, req->hstderr, process,
0, TRUE, DUPLICATE_SAME_ACCESS );
}
process->next = first_process;
first_process->prev = process;
first_process = process;
return process;
error:
release_object( process );
return NULL;
}
/* destroy a process when its refcount is 0 */
@ -135,7 +162,7 @@ static void process_destroy( struct object *obj )
{
struct process *process = (struct process *)obj;
assert( obj->ops == &process_ops );
assert( process != initial_process );
assert( process != &initial_process );
/* we can't have a thread remaining */
assert( !process->thread_list );
@ -144,6 +171,7 @@ static void process_destroy( struct object *obj )
else first_process = process->next;
free_console( process );
free_handles( process );
if (process->info) free( process->info );
if (debug_level) memset( process, 0xbb, sizeof(process) ); /* catch errors */
free( process );
}
@ -163,6 +191,7 @@ static int process_signaled( struct object *obj, struct thread *thread )
return !process->running_threads;
}
/* get a process from an id (and increment the refcount) */
struct process *get_process_from_id( void *id )
{
@ -180,6 +209,20 @@ struct process *get_process_from_handle( int handle, unsigned int access )
access, &process_ops );
}
/* retrieve the initialization info for a new process */
int get_process_init_info( struct process *process, struct init_process_reply *reply )
{
struct new_process_request *info;
if (!(info = process->info)) return 0;
process->info = NULL;
reply->start_flags = info->start_flags;
reply->hstdin = info->hstdin;
reply->hstdout = info->hstdout;
reply->hstderr = info->hstderr;
free( info );
return 1;
}
/* a process has been killed (i.e. its last thread died) */
static void process_killed( struct process *process, int exit_code )
{
@ -296,7 +339,7 @@ static struct handle_entry *get_handle( struct process *process, int handle )
if (HANDLE_IS_GLOBAL(handle))
{
handle = HANDLE_GLOBAL_TO_LOCAL(handle);
process = initial_process;
process = &initial_process;
}
handle--; /* handles start at 1 */
if ((handle < 0) || (handle > process->handle_last)) goto error;
@ -383,7 +426,7 @@ int close_handle( struct process *process, int handle )
if (HANDLE_IS_GLOBAL(handle))
{
handle = HANDLE_GLOBAL_TO_LOCAL(handle);
process = initial_process;
process = &initial_process;
}
if (!(entry = get_handle( process, handle ))) return 0;
if (entry->access & RESERVED_CLOSE_PROTECT) return 0; /* FIXME: error code */
@ -449,7 +492,7 @@ int duplicate_handle( struct process *src, int src_handle, struct process *dst,
if (!entry) return -1;
if (options & DUP_HANDLE_SAME_ACCESS) access = entry->access;
if (options & DUP_HANDLE_MAKE_GLOBAL) dst = initial_process;
if (options & DUP_HANDLE_MAKE_GLOBAL) dst = &initial_process;
access &= ~RESERVED_ALL;
res = alloc_handle( dst, entry->ptr, access, inherit );
if (options & DUP_HANDLE_MAKE_GLOBAL) res = HANDLE_LOCAL_TO_GLOBAL(res);

View File

@ -101,46 +101,63 @@ void call_kill_handler( struct thread *thread, int exit_code )
}
/* create a new process */
DECL_HANDLER(new_process)
{
struct new_process_reply reply;
struct process *process;
if ((process = create_process( req )))
{
reply.pid = process;
reply.handle = alloc_handle( current->process, process,
PROCESS_ALL_ACCESS, req->inherit );
release_object( process );
}
else
{
reply.handle = -1;
reply.pid = NULL;
}
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* create a new thread */
DECL_HANDLER(new_thread)
{
struct new_thread_reply reply;
struct thread *new_thread;
int new_fd, err;
int new_fd;
if ((new_fd = dup(fd)) == -1)
if ((new_fd = dup(fd)) != -1)
{
new_thread = NULL;
err = ERROR_TOO_MANY_OPEN_FILES;
goto done;
}
if (!(new_thread = create_thread( new_fd, req->pid, req->suspend,
req->tinherit, req->pinherit,
&reply.thandle, &reply.phandle )))
{
close( new_fd );
err = ERROR_OUTOFMEMORY;
goto done;
}
reply.tid = new_thread;
reply.pid = new_thread->process;
err = ERROR_SUCCESS;
done:
if (!current)
{
/* first client doesn't have a current */
struct iovec vec = { &reply, sizeof(reply) };
send_reply_v( get_initial_client_fd(), err, -1, &vec, 1 );
reply.tid = create_thread( new_fd, req->pid, req->suspend,
req->inherit, &reply.handle );
if (!reply.tid) close( new_fd );
}
else
{
SET_ERROR( err );
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
SET_ERROR( ERROR_TOO_MANY_OPEN_FILES );
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* create a new thread */
/* initialize a new process */
DECL_HANDLER(init_process)
{
struct init_process_reply reply;
if (current->state != RUNNING)
{
fatal_protocol_error( "init_process: init_thread not called yet\n" );
return;
}
if (!get_process_init_info( current->process, &reply ))
{
fatal_protocol_error( "init_process: called twice\n" );
return;
}
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* initialize a new thread */
DECL_HANDLER(init_thread)
{
if (current->state != STARTING)
@ -150,12 +167,7 @@ DECL_HANDLER(init_thread)
}
current->state = RUNNING;
current->unix_pid = req->unix_pid;
if (!(current->name = mem_alloc( len + 1 ))) goto done;
memcpy( current->name, data, len );
current->name[len] = '\0';
CLEAR_ERROR();
done:
if (current->suspend > 0 && current->unix_pid)
if (current->suspend > 0)
kill( current->unix_pid, SIGSTOP );
send_reply( current, -1, 0 );
}

View File

@ -47,7 +47,6 @@ struct client
struct thread *self; /* client thread (opaque pointer) */
};
static int initial_client_fd; /* fd of the first client */
/* exit code passed to remove_client */
#define OUT_OF_MEMORY -1
@ -258,15 +257,6 @@ static const struct select_ops client_ops =
/*******************************************************************/
/* server-side exported functions */
/* server initialization */
void server_init( int fd )
{
/* special magic to create the initial thread */
initial_client_fd = fd;
add_client( initial_client_fd, NULL );
}
/* add a client */
int add_client( int client_fd, struct thread *self )
{
@ -299,7 +289,6 @@ void remove_client( int client_fd, int exit_code )
call_kill_handler( client->self, exit_code );
remove_select_user( client_fd );
if (initial_client_fd == client_fd) initial_client_fd = -1;
close( client_fd );
/* Purge messages */
@ -308,13 +297,6 @@ void remove_client( int client_fd, int exit_code )
free( client );
}
/* return the fd of the initial client */
int get_initial_client_fd(void)
{
assert( initial_client_fd != -1 );
return initial_client_fd;
}
/* send a reply to a client */
int send_reply_v( int client_fd, int type, int pass_fd,
struct iovec *vec, int veclen )

View File

@ -71,32 +71,15 @@ static const struct object_ops thread_ops =
destroy_thread
};
static struct thread *first_thread;
static struct thread initial_thread;
static struct thread *first_thread = &initial_thread;
/* create a new thread */
struct thread *create_thread( int fd, void *pid, int suspend,
int thread_inherit, int process_inherit,
int *thread_handle, int *process_handle )
/* initialization of a thread structure */
static void init_thread( struct thread *thread, int fd )
{
struct thread *thread;
struct process *process;
if (!(thread = mem_alloc( sizeof(*thread) ))) return NULL;
if (pid) process = get_process_from_id( pid );
else process = create_process();
if (!process)
{
free( thread );
return NULL;
}
init_object( &thread->obj, &thread_ops, NULL );
thread->client_fd = fd;
thread->process = process;
thread->unix_pid = 0; /* not known yet */
thread->name = NULL;
thread->mutex = NULL;
thread->wait = NULL;
thread->apc = NULL;
@ -104,40 +87,58 @@ struct thread *create_thread( int fd, void *pid, int suspend,
thread->error = 0;
thread->state = STARTING;
thread->exit_code = 0x103; /* STILL_ACTIVE */
thread->next = first_thread;
thread->next = NULL;
thread->prev = NULL;
thread->priority = THREAD_PRIORITY_NORMAL;
thread->affinity = 1;
thread->suspend = suspend? 1 : 0;
thread->suspend = 0;
}
if (first_thread) first_thread->prev = thread;
/* create the initial thread and start the main server loop */
void create_initial_thread( int fd )
{
current = &initial_thread;
init_thread( &initial_thread, fd );
initial_thread.process = create_initial_process();
add_process_thread( initial_thread.process, &initial_thread );
add_client( fd, &initial_thread );
select_loop();
}
/* create a new thread */
struct thread *create_thread( int fd, void *pid, int suspend, int inherit, int *handle )
{
struct thread *thread;
struct process *process;
if (!(thread = mem_alloc( sizeof(*thread) ))) return NULL;
if (!(process = get_process_from_id( pid )))
{
free( thread );
return NULL;
}
init_thread( thread, fd );
thread->process = process;
if (suspend) thread->suspend++;
thread->next = first_thread;
first_thread->prev = thread;
first_thread = thread;
add_process_thread( process, thread );
*thread_handle = *process_handle = -1;
if (current)
if ((*handle = alloc_handle( current->process, thread,
THREAD_ALL_ACCESS, inherit )) == -1) goto error;
if (add_client( fd, thread ) == -1)
{
if ((*thread_handle = alloc_handle( current->process, thread,
THREAD_ALL_ACCESS, thread_inherit )) == -1)
goto error;
SET_ERROR( ERROR_TOO_MANY_OPEN_FILES );
goto error;
}
if (current && !pid)
{
if ((*process_handle = alloc_handle( current->process, process,
PROCESS_ALL_ACCESS, process_inherit )) == -1)
goto error;
}
if (add_client( fd, thread ) == -1) goto error;
return thread;
error:
if (current)
{
close_handle( current->process, *thread_handle );
close_handle( current->process, *process_handle );
}
if (current) close_handle( current->process, *handle );
remove_process_thread( process, thread );
release_object( thread );
return NULL;
@ -153,7 +154,6 @@ static void destroy_thread( struct object *obj )
if (thread->next) thread->next->prev = thread->prev;
if (thread->prev) thread->prev->next = thread->next;
else first_thread = thread->next;
if (thread->name) free( thread->name );
if (thread->apc) free( thread->apc );
if (debug_level) memset( thread, 0xaa, sizeof(thread) ); /* catch errors */
free( thread );
@ -165,8 +165,8 @@ static void dump_thread( struct object *obj, int verbose )
struct thread *thread = (struct thread *)obj;
assert( obj->ops == &thread_ops );
fprintf( stderr, "Thread pid=%d fd=%d name='%s'\n",
thread->unix_pid, thread->client_fd, thread->name );
fprintf( stderr, "Thread pid=%d fd=%d\n",
thread->unix_pid, thread->client_fd );
}
static int thread_signaled( struct object *obj, struct thread *thread )
@ -195,7 +195,7 @@ struct thread *get_thread_from_handle( int handle, unsigned int access )
void get_thread_info( struct thread *thread,
struct get_thread_info_reply *reply )
{
reply->pid = thread;
reply->tid = thread;
reply->exit_code = thread->exit_code;
reply->priority = thread->priority;
}

View File

@ -6,21 +6,36 @@
#include "server.h"
#include "server/thread.h"
static int dump_new_process_request( struct new_process_request *req, int len )
{
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " inherit_all=%d,", req->inherit_all );
fprintf( stderr, " start_flags=%d,", req->start_flags );
fprintf( stderr, " hstdin=%d,", req->hstdin );
fprintf( stderr, " hstdout=%d,", req->hstdout );
fprintf( stderr, " hstderr=%d", req->hstderr );
return (int)sizeof(*req);
}
static int dump_new_process_reply( struct new_process_reply *req, int len )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_new_thread_request( struct new_thread_request *req, int len )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " suspend=%d,", req->suspend );
fprintf( stderr, " tinherit=%d,", req->tinherit );
fprintf( stderr, " pinherit=%d", req->pinherit );
fprintf( stderr, " inherit=%d", req->inherit );
return (int)sizeof(*req);
}
static int dump_new_thread_reply( struct new_thread_reply *req, int len )
{
fprintf( stderr, " tid=%p,", req->tid );
fprintf( stderr, " thandle=%d,", req->thandle );
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " phandle=%d", req->phandle );
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
@ -30,11 +45,25 @@ static int dump_set_debug_request( struct set_debug_request *req, int len )
return (int)sizeof(*req);
}
static int dump_init_process_request( struct init_process_request *req, int len )
{
fprintf( stderr, " dummy=%d", req->dummy );
return (int)sizeof(*req);
}
static int dump_init_process_reply( struct init_process_reply *req, int len )
{
fprintf( stderr, " start_flags=%d,", req->start_flags );
fprintf( stderr, " hstdin=%d,", req->hstdin );
fprintf( stderr, " hstdout=%d,", req->hstdout );
fprintf( stderr, " hstderr=%d", req->hstderr );
return (int)sizeof(*req);
}
static int dump_init_thread_request( struct init_thread_request *req, int len )
{
fprintf( stderr, " unix_pid=%d,", req->unix_pid );
fprintf( stderr, " cmd_line=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
return len;
fprintf( stderr, " unix_pid=%d", req->unix_pid );
return (int)sizeof(*req);
}
static int dump_terminate_process_request( struct terminate_process_request *req, int len )
@ -84,7 +113,7 @@ static int dump_get_thread_info_request( struct get_thread_info_request *req, in
static int dump_get_thread_info_reply( struct get_thread_info_reply *req, int len )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " tid=%p,", req->tid );
fprintf( stderr, " exit_code=%d,", req->exit_code );
fprintf( stderr, " priority=%d", req->priority );
return (int)sizeof(*req);
@ -600,10 +629,14 @@ struct dumper
static const struct dumper dumpers[REQ_NB_REQUESTS] =
{
{ (int(*)(void *,int))dump_new_process_request,
(void(*)())dump_new_process_reply },
{ (int(*)(void *,int))dump_new_thread_request,
(void(*)())dump_new_thread_reply },
{ (int(*)(void *,int))dump_set_debug_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_init_process_request,
(void(*)())dump_init_process_reply },
{ (int(*)(void *,int))dump_init_thread_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_terminate_process_request,
@ -708,8 +741,10 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
static const char * const req_names[REQ_NB_REQUESTS] =
{
"new_process",
"new_thread",
"set_debug",
"init_process",
"init_thread",
"terminate_process",
"terminate_thread",