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 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 )
|
||||
|
|
Loading…
Reference in New Issue