server: Store abandoned state as a flag in the wait structure.
This commit is contained in:
parent
39644bb309
commit
d4cd051cef
|
@ -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 )
|
||||||
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
|
||||||
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 )
|
||||||
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 )
|
||||||
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
|
||||||
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
|
||||||
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 );
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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 )
|
||||||
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
|
||||||
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
|
||||||
/* 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 )
|
||||||
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 )
|
||||||
{
|
{
|
||||||
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
|
||||||
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
|
||||||
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 )
|
||||||
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 )
|
||||||
|
|
Loading…
Reference in New Issue