From d4cd051cef5efc5f2898903fb048678e631920c4 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 26 Aug 2013 12:56:41 +0200 Subject: [PATCH] server: Store abandoned state as a flag in the wait structure. --- server/event.c | 5 ++--- server/mutex.c | 8 +++----- server/object.c | 3 +-- server/object.h | 6 +++--- server/queue.c | 5 ++--- server/semaphore.c | 5 ++--- server/thread.c | 22 +++++++++++++--------- server/thread.h | 1 + server/timer.c | 5 ++--- 9 files changed, 29 insertions(+), 31 deletions(-) diff --git a/server/event.c b/server/event.c index beeca7e4987..371f8bfd740 100644 --- a/server/event.c +++ b/server/event.c @@ -46,7 +46,7 @@ struct event static void event_dump( struct object *obj, int verbose ); static struct object_type *event_get_type( struct object *obj ); static int event_signaled( struct object *obj, struct wait_queue_entry *entry ); -static int event_satisfied( struct object *obj, struct wait_queue_entry *entry ); +static void event_satisfied( struct object *obj, struct wait_queue_entry *entry ); static unsigned int event_map_access( struct object *obj, unsigned int access ); static int event_signal( struct object *obj, unsigned int access); @@ -177,13 +177,12 @@ static int event_signaled( struct object *obj, struct wait_queue_entry *entry ) return event->signaled; } -static int event_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void event_satisfied( struct object *obj, struct wait_queue_entry *entry ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); /* Reset if it's an auto-reset event */ if (!event->manual_reset) event->signaled = 0; - return 0; /* Not abandoned */ } static unsigned int event_map_access( struct object *obj, unsigned int access ) diff --git a/server/mutex.c b/server/mutex.c index 7cbfb99e875..3b6f2c04572 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -48,7 +48,7 @@ struct mutex static void mutex_dump( struct object *obj, int verbose ); static struct object_type *mutex_get_type( struct object *obj ); static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry ); -static int mutex_satisfied( struct object *obj, struct wait_queue_entry *entry ); +static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry ); static unsigned int mutex_map_access( struct object *obj, unsigned int access ); static void mutex_destroy( struct object *obj ); static int mutex_signal( struct object *obj, unsigned int access ); @@ -157,16 +157,14 @@ static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry ) return (!mutex->count || (mutex->owner == get_wait_queue_thread( entry ))); } -static int mutex_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); do_grab( mutex, get_wait_queue_thread( entry )); - - if (!mutex->abandoned) return 0; + if (mutex->abandoned) make_wait_abandoned( entry ); mutex->abandoned = 0; - return 1; } static unsigned int mutex_map_access( struct object *obj, unsigned int access ) diff --git a/server/object.c b/server/object.c index e3d47093b32..c2067476b1a 100644 --- a/server/object.c +++ b/server/object.c @@ -393,9 +393,8 @@ int no_add_queue( struct object *obj, struct wait_queue_entry *entry ) return 0; } -int no_satisfied( struct object *obj, struct wait_queue_entry *entry ) +void no_satisfied( struct object *obj, struct wait_queue_entry *entry ) { - return 0; /* not abandoned */ } int no_signal( struct object *obj, unsigned int access ) diff --git a/server/object.h b/server/object.h index 1ea946ae44e..c4932adef88 100644 --- a/server/object.h +++ b/server/object.h @@ -69,8 +69,8 @@ struct object_ops void (*remove_queue)(struct object *,struct wait_queue_entry *); /* is object signaled? */ int (*signaled)(struct object *,struct wait_queue_entry *); - /* wait satisfied; return 1 if abandoned */ - int (*satisfied)(struct object *,struct wait_queue_entry *); + /* wait satisfied */ + void (*satisfied)(struct object *,struct wait_queue_entry *); /* signal an object */ int (*signal)(struct object *, unsigned int); /* return an fd object that can be used to read/write from the object */ @@ -133,7 +133,7 @@ extern struct object *find_object( const struct namespace *namespace, const stru extern struct object *find_object_index( const struct namespace *namespace, unsigned int index ); extern struct object_type *no_get_type( struct object *obj ); extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry ); -extern int no_satisfied( struct object *obj, struct wait_queue_entry *entry ); +extern void no_satisfied( struct object *obj, struct wait_queue_entry *entry ); extern int no_signal( struct object *obj, unsigned int access ); extern struct fd *no_get_fd( struct object *obj ); extern unsigned int no_map_access( struct object *obj, unsigned int access ); diff --git a/server/queue.c b/server/queue.c index 83db3b120c7..c19bb3ab56d 100644 --- a/server/queue.c +++ b/server/queue.c @@ -151,7 +151,7 @@ static void msg_queue_dump( struct object *obj, int verbose ); static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry ); static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry ); static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry ); -static int msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry ); +static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry ); static void msg_queue_destroy( struct object *obj ); static void msg_queue_poll_event( struct fd *fd, int event ); static void thread_input_dump( struct object *obj, int verbose ); @@ -924,12 +924,11 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr return ret || is_signaled( queue ); } -static int msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; queue->wake_mask = 0; queue->changed_mask = 0; - return 0; /* Not abandoned */ } static void msg_queue_destroy( struct object *obj ) diff --git a/server/semaphore.c b/server/semaphore.c index a8366ed5904..109eb9aeed9 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -46,7 +46,7 @@ struct semaphore static void semaphore_dump( struct object *obj, int verbose ); static struct object_type *semaphore_get_type( struct object *obj ); static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry ); -static int semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ); +static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ); static unsigned int semaphore_map_access( struct object *obj, unsigned int access ); static int semaphore_signal( struct object *obj, unsigned int access ); @@ -143,13 +143,12 @@ static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entr return (sem->count > 0); } -static int semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); assert( sem->count ); sem->count--; - return 0; /* not abandoned */ } static unsigned int semaphore_map_access( struct object *obj, unsigned int access ) diff --git a/server/thread.c b/server/thread.c index 8c9e67ab2bc..cd2bf6e6db1 100644 --- a/server/thread.c +++ b/server/thread.c @@ -75,6 +75,7 @@ struct thread_wait struct thread *thread; /* owner thread */ int count; /* count of objects */ int flags; + int abandoned; enum select_op select; client_ptr_t cookie; /* magic cookie to return to client */ timeout_t timeout; @@ -548,6 +549,11 @@ struct thread *get_wait_queue_thread( struct wait_queue_entry *entry ) return entry->wait->thread; } +void make_wait_abandoned( struct wait_queue_entry *entry ) +{ + entry->wait->abandoned = 1; +} + /* finish waiting */ static void end_wait( struct thread *thread ) { @@ -579,6 +585,7 @@ static int wait_on( const select_op_t *select_op, unsigned int count, struct obj wait->select = select_op->op; wait->user = NULL; wait->timeout = timeout; + wait->abandoned = 0; current->wait = wait; for (i = 0, entry = wait->queues; i < count; i++, entry++) @@ -617,7 +624,7 @@ static int wait_on_handles( const select_op_t *select_op, unsigned int count, co /* check if the thread waiting condition is satisfied */ static int check_wait( struct thread *thread ) { - int i, signaled; + int i; struct thread_wait *wait = thread->wait; struct wait_queue_entry *entry; @@ -638,11 +645,9 @@ static int check_wait( struct thread *thread ) not_ok |= !entry->obj->ops->signaled( entry->obj, entry ); if (not_ok) goto other_checks; /* Wait satisfied: tell it to all objects */ - signaled = 0; for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) - if (entry->obj->ops->satisfied( entry->obj, entry )) - signaled = STATUS_ABANDONED_WAIT_0; - return signaled; + entry->obj->ops->satisfied( entry->obj, entry ); + return wait->abandoned ? STATUS_ABANDONED_WAIT_0 : STATUS_WAIT_0; } else { @@ -650,10 +655,9 @@ static int check_wait( struct thread *thread ) { if (!entry->obj->ops->signaled( entry->obj, entry )) continue; /* Wait satisfied: tell it to the object */ - signaled = i; - if (entry->obj->ops->satisfied( entry->obj, entry )) - signaled = i + STATUS_ABANDONED_WAIT_0; - return signaled; + entry->obj->ops->satisfied( entry->obj, entry ); + if (wait->abandoned) i += STATUS_ABANDONED_WAIT_0; + return i; } } diff --git a/server/thread.h b/server/thread.h index c82f7804112..a24a910ca76 100644 --- a/server/thread.h +++ b/server/thread.h @@ -106,6 +106,7 @@ extern struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int extern struct thread *get_thread_from_tid( int tid ); extern struct thread *get_thread_from_pid( int pid ); extern struct thread *get_wait_queue_thread( struct wait_queue_entry *entry ); +extern void make_wait_abandoned( struct wait_queue_entry *entry ); extern void stop_thread( struct thread *thread ); extern void stop_thread_if_suspended( struct thread *thread ); extern int wake_thread( struct thread *thread ); diff --git a/server/timer.c b/server/timer.c index 9832d73937c..9c293f21d52 100644 --- a/server/timer.c +++ b/server/timer.c @@ -53,7 +53,7 @@ struct timer static void timer_dump( struct object *obj, int verbose ); static struct object_type *timer_get_type( struct object *obj ); static int timer_signaled( struct object *obj, struct wait_queue_entry *entry ); -static int timer_satisfied( struct object *obj, struct wait_queue_entry *entry ); +static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry ); static unsigned int timer_map_access( struct object *obj, unsigned int access ); static void timer_destroy( struct object *obj ); @@ -201,12 +201,11 @@ static int timer_signaled( struct object *obj, struct wait_queue_entry *entry ) return timer->signaled; } -static int timer_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry ) { struct timer *timer = (struct timer *)obj; assert( obj->ops == &timer_ops ); if (!timer->manual) timer->signaled = 0; - return 0; } static unsigned int timer_map_access( struct object *obj, unsigned int access )