server: Pass a wait queue entry to the signaled/satisfied object functions.

This commit is contained in:
Alexandre Julliard 2013-08-26 11:55:04 +02:00
parent de9f5b33b8
commit 39644bb309
17 changed files with 86 additions and 78 deletions

View File

@ -53,7 +53,7 @@ struct completion
static void completion_dump( struct object*, int );
static struct object_type *completion_get_type( struct object *obj );
static int completion_signaled( struct object *obj, struct thread *thread );
static int completion_signaled( struct object *obj, struct wait_queue_entry *entry );
static unsigned int completion_map_access( struct object *obj, unsigned int access );
static void completion_destroy( struct object * );
@ -114,7 +114,7 @@ static struct object_type *completion_get_type( struct object *obj )
return get_object_type( &str );
}
static int completion_signaled( struct object *obj, struct thread *thread )
static int completion_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct completion *completion = (struct completion *)obj;

View File

@ -91,7 +91,7 @@ static const struct object_ops console_input_ops =
static void console_input_events_dump( struct object *obj, int verbose );
static void console_input_events_destroy( struct object *obj );
static int console_input_events_signaled( struct object *obj, struct thread *thread );
static int console_input_events_signaled( struct object *obj, struct wait_queue_entry *entry );
struct console_input_events
{
@ -222,7 +222,7 @@ static void console_input_events_destroy( struct object *obj )
}
/* the renderer events list is signaled when it's not empty */
static int console_input_events_signaled( struct object *obj, struct thread *thread )
static int console_input_events_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct console_input_events *evts = (struct console_input_events *)obj;
assert( obj->ops == &console_input_events_ops );

View File

@ -63,7 +63,7 @@ struct debug_ctx
static void debug_event_dump( struct object *obj, int verbose );
static int debug_event_signaled( struct object *obj, struct thread *thread );
static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry );
static void debug_event_destroy( struct object *obj );
static const struct object_ops debug_event_ops =
@ -87,7 +87,7 @@ static const struct object_ops debug_event_ops =
};
static void debug_ctx_dump( struct object *obj, int verbose );
static int debug_ctx_signaled( struct object *obj, struct thread *thread );
static int debug_ctx_signaled( struct object *obj, struct wait_queue_entry *entry );
static void debug_ctx_destroy( struct object *obj );
static const struct object_ops debug_ctx_ops =
@ -274,7 +274,7 @@ static void debug_event_dump( struct object *obj, int verbose )
debug_event->sender, debug_event->data.code, debug_event->state );
}
static int debug_event_signaled( struct object *obj, struct thread *thread )
static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct debug_event *debug_event = (struct debug_event *)obj;
assert( obj->ops == &debug_event_ops );
@ -325,7 +325,7 @@ static void debug_ctx_dump( struct object *obj, int verbose )
debug_ctx->event_queue.next, debug_ctx->event_queue.prev );
}
static int debug_ctx_signaled( struct object *obj, struct thread *thread )
static int debug_ctx_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
assert( obj->ops == &debug_ctx_ops );

View File

@ -52,7 +52,7 @@ struct ioctl_call
};
static void ioctl_call_dump( struct object *obj, int verbose );
static int ioctl_call_signaled( struct object *obj, struct thread *thread );
static int ioctl_call_signaled( struct object *obj, struct wait_queue_entry *entry );
static void ioctl_call_destroy( struct object *obj );
static const struct object_ops ioctl_call_ops =
@ -84,7 +84,7 @@ struct device_manager
};
static void device_manager_dump( struct object *obj, int verbose );
static int device_manager_signaled( struct object *obj, struct thread *thread );
static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry );
static void device_manager_destroy( struct object *obj );
static const struct object_ops device_manager_ops =
@ -167,7 +167,7 @@ static void ioctl_call_dump( struct object *obj, int verbose )
fprintf( stderr, "Ioctl call code=%08x device=%p\n", ioctl->code, ioctl->device );
}
static int ioctl_call_signaled( struct object *obj, struct thread *thread )
static int ioctl_call_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct ioctl_call *ioctl = (struct ioctl_call *)obj;
@ -394,7 +394,7 @@ static void device_manager_dump( struct object *obj, int verbose )
fprintf( stderr, "Device manager\n" );
}
static int device_manager_signaled( struct object *obj, struct thread *thread )
static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct device_manager *manager = (struct device_manager *)obj;

View File

@ -45,8 +45,8 @@ 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 thread *thread );
static int event_satisfied( struct object *obj, struct thread *thread );
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 unsigned int event_map_access( struct object *obj, unsigned int access );
static int event_signal( struct object *obj, unsigned int access);
@ -78,7 +78,7 @@ struct keyed_event
static void keyed_event_dump( struct object *obj, int verbose );
static struct object_type *keyed_event_get_type( struct object *obj );
static int keyed_event_signaled( struct object *obj, struct thread *thread );
static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *entry );
static unsigned int keyed_event_map_access( struct object *obj, unsigned int access );
static const struct object_ops keyed_event_ops =
@ -170,14 +170,14 @@ static struct object_type *event_get_type( struct object *obj )
return get_object_type( &str );
}
static int event_signaled( struct object *obj, struct thread *thread )
static int event_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops );
return event->signaled;
}
static int event_satisfied( struct object *obj, struct thread *thread )
static int event_satisfied( struct object *obj, struct wait_queue_entry *entry )
{
struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops );
@ -244,7 +244,7 @@ static struct object_type *keyed_event_get_type( struct object *obj )
return get_object_type( &str );
}
static int keyed_event_signaled( struct object *obj, struct thread *thread )
static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *entry )
{
assert( obj->ops == &keyed_event_ops );
return 1;

View File

@ -302,7 +302,7 @@ struct file_lock
};
static void file_lock_dump( struct object *obj, int verbose );
static int file_lock_signaled( struct object *obj, struct thread *thread );
static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry );
static const struct object_ops file_lock_ops =
{
@ -1128,7 +1128,7 @@ static void file_lock_dump( struct object *obj, int verbose )
fprintf( stderr, "\n" );
}
static int file_lock_signaled( struct object *obj, struct thread *thread )
static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct file_lock *lock = (struct file_lock *)obj;
/* lock is signaled if it has lost its owner */
@ -1968,7 +1968,7 @@ int check_fd_events( struct fd *fd, int events )
}
/* default signaled() routine for objects that poll() on an fd */
int default_fd_signaled( struct object *obj, struct thread *thread )
int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct fd *fd = get_obj_fd( obj );
int ret = fd->signaled;

View File

@ -77,7 +77,7 @@ extern void allow_fd_caching( struct fd *fd );
extern void set_fd_signaled( struct fd *fd, int signaled );
extern int is_fd_signaled( struct fd *fd );
extern int default_fd_signaled( struct object *obj, struct thread *thread );
extern int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry );
extern unsigned int default_fd_map_access( struct object *obj, unsigned int access );
extern int default_fd_get_poll_events( struct fd *fd );
extern void default_poll_event( struct fd *fd, int event );

View File

@ -47,8 +47,8 @@ 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 thread *thread );
static int mutex_satisfied( struct object *obj, struct thread *thread );
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 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 );
@ -74,6 +74,29 @@ static const struct object_ops mutex_ops =
};
/* grab a mutex for a given thread */
static void do_grab( struct mutex *mutex, struct thread *thread )
{
assert( !mutex->count || (mutex->owner == thread) );
if (!mutex->count++) /* FIXME: avoid wrap-around */
{
assert( !mutex->owner );
mutex->owner = thread;
list_add_head( &thread->mutex_list, &mutex->entry );
}
}
/* release a mutex once the recursion count is 0 */
static void do_release( struct mutex *mutex )
{
assert( !mutex->count );
/* remove the mutex from the thread list of owned mutexes */
list_remove( &mutex->entry );
mutex->owner = NULL;
wake_up( &mutex->obj, 0 );
}
static struct mutex *create_mutex( struct directory *root, const struct unicode_str *name,
unsigned int attr, int owned, const struct security_descriptor *sd )
{
@ -87,7 +110,7 @@ static struct mutex *create_mutex( struct directory *root, const struct unicode_
mutex->count = 0;
mutex->owner = NULL;
mutex->abandoned = 0;
if (owned) mutex_satisfied( &mutex->obj, current );
if (owned) do_grab( mutex, current );
if (sd) default_set_sd( &mutex->obj, sd, OWNER_SECURITY_INFORMATION|
GROUP_SECURITY_INFORMATION|
DACL_SECURITY_INFORMATION|
@ -97,16 +120,6 @@ static struct mutex *create_mutex( struct directory *root, const struct unicode_
return mutex;
}
/* release a mutex once the recursion count is 0 */
static void do_release( struct mutex *mutex )
{
assert( !mutex->count );
/* remove the mutex from the thread list of owned mutexes */
list_remove( &mutex->entry );
mutex->owner = NULL;
wake_up( &mutex->obj, 0 );
}
void abandon_mutexes( struct thread *thread )
{
struct list *ptr;
@ -137,25 +150,20 @@ static struct object_type *mutex_get_type( struct object *obj )
return get_object_type( &str );
}
static int mutex_signaled( struct object *obj, struct thread *thread )
static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
return (!mutex->count || (mutex->owner == thread));
return (!mutex->count || (mutex->owner == get_wait_queue_thread( entry )));
}
static int mutex_satisfied( struct object *obj, struct thread *thread )
static int mutex_satisfied( struct object *obj, struct wait_queue_entry *entry )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
assert( !mutex->count || (mutex->owner == thread) );
if (!mutex->count++) /* FIXME: avoid wrap-around */
{
assert( !mutex->owner );
mutex->owner = thread;
list_add_head( &thread->mutex_list, &mutex->entry );
}
do_grab( mutex, get_wait_queue_thread( entry ));
if (!mutex->abandoned) return 0;
mutex->abandoned = 0;
return 1;

View File

@ -177,7 +177,7 @@ static const struct fd_ops pipe_server_fd_ops =
/* client end functions */
static void pipe_client_dump( struct object *obj, int verbose );
static int pipe_client_signaled( struct object *obj, struct thread *thread );
static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct fd *pipe_client_get_fd( struct object *obj );
static void pipe_client_destroy( struct object *obj );
static void pipe_client_flush( struct fd *fd, struct event **event );
@ -291,7 +291,7 @@ static void pipe_client_dump( struct object *obj, int verbose )
fprintf( stderr, "Named pipe client server=%p\n", client->server );
}
static int pipe_client_signaled( struct object *obj, struct thread *thread )
static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct pipe_client *client = (struct pipe_client *) obj;

View File

@ -393,7 +393,7 @@ int no_add_queue( struct object *obj, struct wait_queue_entry *entry )
return 0;
}
int no_satisfied( struct object *obj, struct thread *thread )
int no_satisfied( struct object *obj, struct wait_queue_entry *entry )
{
return 0; /* not abandoned */
}

View File

@ -68,9 +68,9 @@ struct object_ops
/* remove a thread from the object wait queue */
void (*remove_queue)(struct object *,struct wait_queue_entry *);
/* is object signaled? */
int (*signaled)(struct object *,struct thread *);
int (*signaled)(struct object *,struct wait_queue_entry *);
/* wait satisfied; return 1 if abandoned */
int (*satisfied)(struct object *,struct thread *);
int (*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 thread *thread );
extern int 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 );

View File

@ -60,7 +60,7 @@ static int shutdown_stage; /* current stage in the shutdown process */
/* process operations */
static void process_dump( struct object *obj, int verbose );
static int process_signaled( struct object *obj, struct thread *thread );
static int process_signaled( struct object *obj, struct wait_queue_entry *entry );
static unsigned int process_map_access( struct object *obj, unsigned int access );
static void process_poll_event( struct fd *fd, int event );
static void process_destroy( struct object *obj );
@ -110,7 +110,7 @@ struct startup_info
};
static void startup_info_dump( struct object *obj, int verbose );
static int startup_info_signaled( struct object *obj, struct thread *thread );
static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry );
static void startup_info_destroy( struct object *obj );
static const struct object_ops startup_info_ops =
@ -441,7 +441,7 @@ static void process_dump( struct object *obj, int verbose )
fprintf( stderr, "Process id=%04x handles=%p\n", process->id, process->handles );
}
static int process_signaled( struct object *obj, struct thread *thread )
static int process_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct process *process = (struct process *)obj;
return !process->running_threads;
@ -483,7 +483,7 @@ static void startup_info_dump( struct object *obj, int verbose )
info->data->hstdin, info->data->hstdout, info->data->hstderr );
}
static int startup_info_signaled( struct object *obj, struct thread *thread )
static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct startup_info *info = (struct startup_info *)obj;
return info->process && info->process->startup_state != STARTUP_IN_PROGRESS;

View File

@ -150,8 +150,8 @@ struct hotkey
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 thread *thread );
static int msg_queue_satisfied( struct object *obj, struct thread *thread );
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_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 );
@ -907,7 +907,7 @@ static void msg_queue_dump( struct object *obj, int verbose )
queue->wake_bits, queue->wake_mask );
}
static int msg_queue_signaled( struct object *obj, struct thread *thread )
static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct msg_queue *queue = (struct msg_queue *)obj;
int ret = 0;
@ -924,7 +924,7 @@ static int msg_queue_signaled( struct object *obj, struct thread *thread )
return ret || is_signaled( queue );
}
static int msg_queue_satisfied( struct object *obj, struct thread *thread )
static int msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry )
{
struct msg_queue *queue = (struct msg_queue *)obj;
queue->wake_mask = 0;
@ -2198,7 +2198,7 @@ DECL_HANDLER(set_queue_mask)
if (is_signaled( queue ))
{
/* if skip wait is set, do what would have been done in the subsequent wait */
if (req->skip_wait) msg_queue_satisfied( &queue->obj, current );
if (req->skip_wait) queue->wake_mask = queue->changed_mask = 0;
else wake_up( &queue->obj, 0 );
}
}

View File

@ -45,8 +45,8 @@ 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 thread *thread );
static int semaphore_satisfied( struct object *obj, struct thread *thread );
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 unsigned int semaphore_map_access( struct object *obj, unsigned int access );
static int semaphore_signal( struct object *obj, unsigned int access );
@ -136,14 +136,14 @@ static struct object_type *semaphore_get_type( struct object *obj )
return get_object_type( &str );
}
static int semaphore_signaled( struct object *obj, struct thread *thread )
static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops );
return (sem->count > 0);
}
static int semaphore_satisfied( struct object *obj, struct thread *thread )
static int semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry )
{
struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops );

View File

@ -109,7 +109,7 @@ struct sock
};
static void sock_dump( struct object *obj, int verbose );
static int sock_signaled( struct object *obj, struct thread *thread );
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct fd *sock_get_fd( struct object *obj );
static void sock_destroy( struct object *obj );
@ -470,7 +470,7 @@ static void sock_dump( struct object *obj, int verbose )
sock->mask, sock->pmask, sock->hmask );
}
static int sock_signaled( struct object *obj, struct thread *thread )
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct sock *sock = (struct sock *)obj;
assert( obj->ops == &sock_ops );

View File

@ -96,7 +96,7 @@ struct thread_apc
};
static void dump_thread_apc( struct object *obj, int verbose );
static int thread_apc_signaled( struct object *obj, struct thread *thread );
static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry );
static void thread_apc_destroy( struct object *obj );
static void clear_apc_queue( struct list *queue );
@ -124,7 +124,7 @@ static const struct object_ops thread_apc_ops =
/* thread operations */
static void dump_thread( struct object *obj, int verbose );
static int thread_signaled( struct object *obj, struct thread *thread );
static int thread_signaled( struct object *obj, struct wait_queue_entry *entry );
static unsigned int thread_map_access( struct object *obj, unsigned int access );
static void thread_poll_event( struct fd *fd, int event );
static void destroy_thread( struct object *obj );
@ -321,7 +321,7 @@ static void dump_thread( struct object *obj, int verbose )
thread->id, thread->unix_pid, thread->unix_tid, thread->state );
}
static int thread_signaled( struct object *obj, struct thread *thread )
static int thread_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct thread *mythread = (struct thread *)obj;
return (mythread->state == TERMINATED);
@ -344,7 +344,7 @@ static void dump_thread_apc( struct object *obj, int verbose )
fprintf( stderr, "APC owner=%p type=%u\n", apc->owner, apc->call.type );
}
static int thread_apc_signaled( struct object *obj, struct thread *thread )
static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct thread_apc *apc = (struct thread_apc *)obj;
return apc->executed;
@ -635,12 +635,12 @@ static int check_wait( struct thread *thread )
/* Note: we must check them all anyway, as some objects may
* want to do something when signaled, even if others are not */
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
not_ok |= !entry->obj->ops->signaled( entry->obj, 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, thread ))
if (entry->obj->ops->satisfied( entry->obj, entry ))
signaled = STATUS_ABANDONED_WAIT_0;
return signaled;
}
@ -648,10 +648,10 @@ static int check_wait( struct thread *thread )
{
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
{
if (!entry->obj->ops->signaled( entry->obj, thread )) continue;
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, thread ))
if (entry->obj->ops->satisfied( entry->obj, entry ))
signaled = i + STATUS_ABANDONED_WAIT_0;
return signaled;
}

View File

@ -52,8 +52,8 @@ 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 thread *thread );
static int timer_satisfied( struct object *obj, struct thread *thread );
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 unsigned int timer_map_access( struct object *obj, unsigned int access );
static void timer_destroy( struct object *obj );
@ -194,14 +194,14 @@ static struct object_type *timer_get_type( struct object *obj )
return get_object_type( &str );
}
static int timer_signaled( struct object *obj, struct thread *thread )
static int timer_signaled( struct object *obj, struct wait_queue_entry *entry )
{
struct timer *timer = (struct timer *)obj;
assert( obj->ops == &timer_ops );
return timer->signaled;
}
static int timer_satisfied( struct object *obj, struct thread *thread )
static int timer_satisfied( struct object *obj, struct wait_queue_entry *entry )
{
struct timer *timer = (struct timer *)obj;
assert( obj->ops == &timer_ops );