From 15979fda7592a3c62cb64d19132cba20831bb60c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 23 Mar 2002 18:50:04 +0000 Subject: [PATCH] Fixed handling of timer callback routines when the thread owning the callback terminates. --- server/thread.c | 1 + server/timer.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/server/thread.c b/server/thread.c index 09ad63b4023..eba63e18d84 100644 --- a/server/thread.c +++ b/server/thread.c @@ -554,6 +554,7 @@ int thread_queue_apc( struct thread *thread, struct object *owner, void *func, /* cancel a possible previous APC with the same owner */ if (owner) thread_cancel_apc( thread, owner, system ); + if (thread->state == TERMINATED) return 0; if (!(apc = mem_alloc( sizeof(*apc) + (nb_args-1)*sizeof(apc->args[0]) ))) return 0; apc->prev = queue->tail; diff --git a/server/timer.c b/server/timer.c index 7120ef5ae8e..0391d2fa779 100644 --- a/server/timer.c +++ b/server/timer.c @@ -93,8 +93,14 @@ static void timer_callback( void *private ) /* queue an APC */ if (timer->thread) - thread_queue_apc( timer->thread, &timer->obj, timer->callback, APC_TIMER, 0, 3, - (void *)timer->when.tv_sec, (void *)timer->when.tv_usec, timer->arg ); + { + if (!thread_queue_apc( timer->thread, &timer->obj, timer->callback, APC_TIMER, 0, 3, + (void *)timer->when.tv_sec, (void *)timer->when.tv_usec, timer->arg)) + { + release_object( timer->thread ); + timer->thread = NULL; + } + } if (timer->period) /* schedule the next expiration */ { @@ -119,6 +125,7 @@ static void cancel_timer( struct timer *timer ) if (timer->thread) { thread_cancel_apc( timer->thread, &timer->obj, 0 ); + release_object( timer->thread ); timer->thread = NULL; } } @@ -147,7 +154,7 @@ static void set_timer( struct timer *timer, int sec, int usec, int period, timer->period = period; timer->callback = callback; timer->arg = arg; - if (callback) timer->thread = current; + if (callback) timer->thread = (struct thread *)grab_object( current ); timer->timeout = add_timeout_user( &timer->when, timer_callback, timer ); } @@ -182,6 +189,7 @@ static void timer_destroy( struct object *obj ) assert( obj->ops == &timer_ops ); if (timer->timeout) remove_timeout_user( timer->timeout ); + if (timer->thread) release_object( timer->thread ); } /* create a timer */