Fixed handling of timer callback routines when the thread owning the
callback terminates.
diff --git a/server/timer.c b/server/timer.c
index 7120ef5..0391d2f 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -93,8 +93,14 @@
/* 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 @@
if (timer->thread)
{
thread_cancel_apc( timer->thread, &timer->obj, 0 );
+ release_object( timer->thread );
timer->thread = NULL;
}
}
@@ -147,7 +154,7 @@
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 @@
assert( obj->ops == &timer_ops );
if (timer->timeout) remove_timeout_user( timer->timeout );
+ if (timer->thread) release_object( timer->thread );
}
/* create a timer */