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
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 )
......
......@@ -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 )
......
......@@ -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 )
......
......@@ -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 );
......
......@@ -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 )
......
......@@ -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 )
......
......@@ -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;
}
}
......
......@@ -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 );
......
......@@ -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 )
......
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