Commit d4cd051c authored by Alexandre Julliard's avatar Alexandre Julliard

server: Store abandoned state as a flag in the wait structure.

parent 39644bb3
...@@ -46,7 +46,7 @@ struct event ...@@ -46,7 +46,7 @@ struct event
static void event_dump( struct object *obj, int verbose ); static void event_dump( struct object *obj, int verbose );
static struct object_type *event_get_type( struct object *obj ); 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_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 unsigned int event_map_access( struct object *obj, unsigned int access );
static int event_signal( 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 ) ...@@ -177,13 +177,12 @@ static int event_signaled( struct object *obj, struct wait_queue_entry *entry )
return event->signaled; 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; struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops ); assert( obj->ops == &event_ops );
/* Reset if it's an auto-reset event */ /* Reset if it's an auto-reset event */
if (!event->manual_reset) event->signaled = 0; if (!event->manual_reset) event->signaled = 0;
return 0; /* Not abandoned */
} }
static unsigned int event_map_access( struct object *obj, unsigned int access ) static unsigned int event_map_access( struct object *obj, unsigned int access )
......
...@@ -48,7 +48,7 @@ struct mutex ...@@ -48,7 +48,7 @@ struct mutex
static void mutex_dump( struct object *obj, int verbose ); static void mutex_dump( struct object *obj, int verbose );
static struct object_type *mutex_get_type( struct object *obj ); 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_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 unsigned int mutex_map_access( struct object *obj, unsigned int access );
static void mutex_destroy( struct object *obj ); static void mutex_destroy( struct object *obj );
static int mutex_signal( struct object *obj, unsigned int access ); 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 ) ...@@ -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 ))); 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; struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops ); assert( obj->ops == &mutex_ops );
do_grab( mutex, get_wait_queue_thread( entry )); do_grab( mutex, get_wait_queue_thread( entry ));
if (mutex->abandoned) make_wait_abandoned( entry );
if (!mutex->abandoned) return 0;
mutex->abandoned = 0; mutex->abandoned = 0;
return 1;
} }
static unsigned int mutex_map_access( struct object *obj, unsigned int access ) static unsigned int mutex_map_access( struct object *obj, unsigned int access )
......
...@@ -393,9 +393,8 @@ int no_add_queue( struct object *obj, struct wait_queue_entry *entry ) ...@@ -393,9 +393,8 @@ int no_add_queue( struct object *obj, struct wait_queue_entry *entry )
return 0; 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 ) int no_signal( struct object *obj, unsigned int access )
......
...@@ -69,8 +69,8 @@ struct object_ops ...@@ -69,8 +69,8 @@ struct object_ops
void (*remove_queue)(struct object *,struct wait_queue_entry *); void (*remove_queue)(struct object *,struct wait_queue_entry *);
/* is object signaled? */ /* is object signaled? */
int (*signaled)(struct object *,struct wait_queue_entry *); int (*signaled)(struct object *,struct wait_queue_entry *);
/* wait satisfied; return 1 if abandoned */ /* wait satisfied */
int (*satisfied)(struct object *,struct wait_queue_entry *); void (*satisfied)(struct object *,struct wait_queue_entry *);
/* signal an object */ /* signal an object */
int (*signal)(struct object *, unsigned int); int (*signal)(struct object *, unsigned int);
/* return an fd object that can be used to read/write from the object */ /* 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 ...@@ -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 *find_object_index( const struct namespace *namespace, unsigned int index );
extern struct object_type *no_get_type( struct object *obj ); 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_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 int no_signal( struct object *obj, unsigned int access );
extern struct fd *no_get_fd( struct object *obj ); extern struct fd *no_get_fd( struct object *obj );
extern unsigned int no_map_access( struct object *obj, unsigned int access ); extern unsigned int no_map_access( struct object *obj, unsigned int access );
......
...@@ -151,7 +151,7 @@ static void msg_queue_dump( struct object *obj, int verbose ); ...@@ -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 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 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_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_destroy( struct object *obj );
static void msg_queue_poll_event( struct fd *fd, int event ); static void msg_queue_poll_event( struct fd *fd, int event );
static void thread_input_dump( struct object *obj, int verbose ); 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 ...@@ -924,12 +924,11 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr
return ret || is_signaled( queue ); 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; struct msg_queue *queue = (struct msg_queue *)obj;
queue->wake_mask = 0; queue->wake_mask = 0;
queue->changed_mask = 0; queue->changed_mask = 0;
return 0; /* Not abandoned */
} }
static void msg_queue_destroy( struct object *obj ) static void msg_queue_destroy( struct object *obj )
......
...@@ -46,7 +46,7 @@ struct semaphore ...@@ -46,7 +46,7 @@ struct semaphore
static void semaphore_dump( struct object *obj, int verbose ); static void semaphore_dump( struct object *obj, int verbose );
static struct object_type *semaphore_get_type( struct object *obj ); 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_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 unsigned int semaphore_map_access( struct object *obj, unsigned int access );
static int semaphore_signal( 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 ...@@ -143,13 +143,12 @@ static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entr
return (sem->count > 0); 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; struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops ); assert( obj->ops == &semaphore_ops );
assert( sem->count ); assert( sem->count );
sem->count--; sem->count--;
return 0; /* not abandoned */
} }
static unsigned int semaphore_map_access( struct object *obj, unsigned int access ) static unsigned int semaphore_map_access( struct object *obj, unsigned int access )
......
...@@ -75,6 +75,7 @@ struct thread_wait ...@@ -75,6 +75,7 @@ struct thread_wait
struct thread *thread; /* owner thread */ struct thread *thread; /* owner thread */
int count; /* count of objects */ int count; /* count of objects */
int flags; int flags;
int abandoned;
enum select_op select; enum select_op select;
client_ptr_t cookie; /* magic cookie to return to client */ client_ptr_t cookie; /* magic cookie to return to client */
timeout_t timeout; timeout_t timeout;
...@@ -548,6 +549,11 @@ struct thread *get_wait_queue_thread( struct wait_queue_entry *entry ) ...@@ -548,6 +549,11 @@ struct thread *get_wait_queue_thread( struct wait_queue_entry *entry )
return entry->wait->thread; return entry->wait->thread;
} }
void make_wait_abandoned( struct wait_queue_entry *entry )
{
entry->wait->abandoned = 1;
}
/* finish waiting */ /* finish waiting */
static void end_wait( struct thread *thread ) 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 ...@@ -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->select = select_op->op;
wait->user = NULL; wait->user = NULL;
wait->timeout = timeout; wait->timeout = timeout;
wait->abandoned = 0;
current->wait = wait; current->wait = wait;
for (i = 0, entry = wait->queues; i < count; i++, entry++) 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 ...@@ -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 */ /* check if the thread waiting condition is satisfied */
static int check_wait( struct thread *thread ) static int check_wait( struct thread *thread )
{ {
int i, signaled; int i;
struct thread_wait *wait = thread->wait; struct thread_wait *wait = thread->wait;
struct wait_queue_entry *entry; struct wait_queue_entry *entry;
...@@ -638,11 +645,9 @@ static int check_wait( struct thread *thread ) ...@@ -638,11 +645,9 @@ static int check_wait( struct thread *thread )
not_ok |= !entry->obj->ops->signaled( entry->obj, entry ); not_ok |= !entry->obj->ops->signaled( entry->obj, entry );
if (not_ok) goto other_checks; if (not_ok) goto other_checks;
/* Wait satisfied: tell it to all objects */ /* Wait satisfied: tell it to all objects */
signaled = 0;
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
if (entry->obj->ops->satisfied( entry->obj, entry )) entry->obj->ops->satisfied( entry->obj, entry );
signaled = STATUS_ABANDONED_WAIT_0; return wait->abandoned ? STATUS_ABANDONED_WAIT_0 : STATUS_WAIT_0;
return signaled;
} }
else else
{ {
...@@ -650,10 +655,9 @@ static int check_wait( struct thread *thread ) ...@@ -650,10 +655,9 @@ static int check_wait( struct thread *thread )
{ {
if (!entry->obj->ops->signaled( entry->obj, entry )) continue; if (!entry->obj->ops->signaled( entry->obj, entry )) continue;
/* Wait satisfied: tell it to the object */ /* Wait satisfied: tell it to the object */
signaled = i; entry->obj->ops->satisfied( entry->obj, entry );
if (entry->obj->ops->satisfied( entry->obj, entry )) if (wait->abandoned) i += STATUS_ABANDONED_WAIT_0;
signaled = i + STATUS_ABANDONED_WAIT_0; return i;
return signaled;
} }
} }
......
...@@ -106,6 +106,7 @@ extern struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int ...@@ -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_tid( int tid );
extern struct thread *get_thread_from_pid( int pid ); extern struct thread *get_thread_from_pid( int pid );
extern struct thread *get_wait_queue_thread( struct wait_queue_entry *entry ); 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( struct thread *thread );
extern void stop_thread_if_suspended( struct thread *thread ); extern void stop_thread_if_suspended( struct thread *thread );
extern int wake_thread( struct thread *thread ); extern int wake_thread( struct thread *thread );
......
...@@ -53,7 +53,7 @@ struct timer ...@@ -53,7 +53,7 @@ struct timer
static void timer_dump( struct object *obj, int verbose ); static void timer_dump( struct object *obj, int verbose );
static struct object_type *timer_get_type( struct object *obj ); 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_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 unsigned int timer_map_access( struct object *obj, unsigned int access );
static void timer_destroy( struct object *obj ); static void timer_destroy( struct object *obj );
...@@ -201,12 +201,11 @@ static int timer_signaled( struct object *obj, struct wait_queue_entry *entry ) ...@@ -201,12 +201,11 @@ static int timer_signaled( struct object *obj, struct wait_queue_entry *entry )
return timer->signaled; 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; struct timer *timer = (struct timer *)obj;
assert( obj->ops == &timer_ops ); assert( obj->ops == &timer_ops );
if (!timer->manual) timer->signaled = 0; if (!timer->manual) timer->signaled = 0;
return 0;
} }
static unsigned int timer_map_access( struct object *obj, unsigned int access ) static unsigned int timer_map_access( struct object *obj, unsigned int access )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment