Module: wine Branch: master Commit: 68e850e602975b4669e7284f4b32b2d4f33b4a32 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=68e850e602975b4669e7284f...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Aug 14 20:19:42 2006 +0200
server: Send a SIGKILL to processes that don't terminate properly.
---
server/process.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- server/process.h | 2 ++ server/thread.c | 3 +++ 3 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/server/process.c b/server/process.c index 3f933fe..733b1c5 100644 --- a/server/process.c +++ b/server/process.c @@ -217,6 +217,38 @@ static void set_process_startup_state( s } }
+/* final cleanup once we are sure a process is really dead */ +static void process_died( struct process *process ) +{ + if (debug_level) fprintf( stderr, "%04x: *process killed*\n", process->id ); + release_object( process ); + if (!--running_processes) close_master_socket(); +} + +/* callback for process sigkill timeout */ +static void process_sigkill( void *private ) +{ + struct process *process = private; + + process->sigkill_timeout = NULL; + kill( process->unix_pid, SIGKILL ); + process_died( process ); +} + +/* start the sigkill timer for a process upon exit */ +static void start_sigkill_timer( struct process *process ) +{ + grab_object( process ); + if (process->unix_pid != -1 && process->msg_fd) + { + struct timeval when = current_time; + + add_timeout( &when, 1000 ); + process->sigkill_timeout = add_timeout_user( &when, process_sigkill, process ); + } + else process_died( process ); +} + /* create a new process and its main thread */ /* if the function fails the fd is closed */ struct thread *create_process( int fd, struct thread *parent_thread, int inherit_all ) @@ -234,6 +266,8 @@ struct thread *create_process( int fd, s process->debugger = NULL; process->handles = NULL; process->msg_fd = NULL; + process->sigkill_timeout = NULL; + process->unix_pid = -1; process->exit_code = STILL_ACTIVE; process->running_threads = 0; process->priority = PROCESS_PRIOCLASS_NORMAL; @@ -322,6 +356,8 @@ static void process_destroy( struct obje /* we can't have a thread remaining */ assert( list_empty( &process->thread_list ));
+ assert( !process->sigkill_timeout ); /* timeout should hold a reference to the process */ + set_process_startup_state( process, STARTUP_ABORTED ); if (process->console) release_object( process->console ); if (process->parent) release_object( process->parent ); @@ -362,7 +398,18 @@ static void process_poll_event( struct f struct process *process = get_fd_user( fd ); assert( process->obj.ops == &process_ops );
- if (event & (POLLERR | POLLHUP)) set_fd_events( fd, -1 ); + if (event & (POLLERR | POLLHUP)) + { + release_object( process->msg_fd ); + process->msg_fd = NULL; + if (process->sigkill_timeout) /* already waiting for it to die */ + { + remove_timeout_user( process->sigkill_timeout ); + process->sigkill_timeout = NULL; + process_died( process ); + } + else kill_process( process, NULL, 0 ); + } else if (event & POLLIN) receive_fd( process ); }
@@ -528,8 +575,8 @@ static void process_killed( struct proce destroy_process_classes( process ); remove_process_locks( process ); set_process_startup_state( process, STARTUP_ABORTED ); + start_sigkill_timer( process ); wake_up( &process->obj, 0 ); - if (!--running_processes) close_master_socket(); }
/* add a thread to a process running threads list */ diff --git a/server/process.h b/server/process.h index 6edb1e6..c447e2f 100644 --- a/server/process.h +++ b/server/process.h @@ -57,6 +57,8 @@ struct process struct fd *msg_fd; /* fd for sendmsg/recvmsg */ process_id_t id; /* id of the process */ process_id_t group_id; /* group id of the process */ + struct timeout_user *sigkill_timeout; /* timeout for final SIGKILL */ + int unix_pid; /* Unix pid for final SIGKILL */ int exit_code; /* process exit code */ int running_threads; /* number of threads running in this process */ struct timeval start_time; /* absolute time at process start */ diff --git a/server/thread.c b/server/thread.c index 9d9f255..36d1d79 100644 --- a/server/thread.c +++ b/server/thread.c @@ -872,12 +872,15 @@ DECL_HANDLER(init_thread)
if (!process->peb) /* first thread, initialize the process too */ { + process->unix_pid = current->unix_pid; process->peb = req->peb; process->ldt_copy = req->ldt_copy; reply->info_size = init_process( current ); } else { + if (process->unix_pid != current->unix_pid) + process->unix_pid = -1; /* can happen with linuxthreads */ if (current->suspend + process->suspend > 0) stop_thread( current ); generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT, req->entry ); }