From: Rémi Bernon rbernon@codeweavers.com
--- server/event.c | 8 +++++--- server/mutex.c | 10 ++++++---- server/object.c | 2 +- server/object.h | 8 +++++--- server/semaphore.c | 8 +++++--- server/thread.c | 2 +- 6 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/server/event.c b/server/event.c index bca7a0010f0..f0565757670 100644 --- a/server/event.c +++ b/server/event.c @@ -64,7 +64,7 @@ static struct sync *event_get_sync( struct object *obj ); static void event_destroy( struct object *obj ); static int event_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void event_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); -static int event_signal( struct sync *sync, struct object *obj, unsigned int access ); +static int event_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ); static struct list *event_get_kernel_obj_list( struct object *obj );
static const struct sync_ops event_sync_ops = @@ -238,16 +238,18 @@ static void event_satisfied( struct sync *sync, struct object *obj, struct wait_ if (!event->manual_reset) event->signaled = 0; }
-static int event_signal( struct sync *sync, struct object *obj, unsigned int access ) +static int event_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops );
- if (!(access & EVENT_MODIFY_STATE)) + if (signal == SIGNAL_SELECT && !(access & EVENT_MODIFY_STATE)) { set_error( STATUS_ACCESS_DENIED ); return 0; } + + assert( signal == SIGNAL_SELECT ); set_event( event ); return 1; } diff --git a/server/mutex.c b/server/mutex.c index 761da93dd1f..42a5c3500a1 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -65,7 +65,7 @@ static struct sync *mutex_get_sync( struct object *obj ); static int mutex_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void mutex_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void mutex_destroy( struct object *obj ); -static int mutex_signal( struct sync *sync, struct object *obj, unsigned int access ); +static int mutex_signal( struct sync *sync, struct object *obj, int signal, unsigned int access );
static const struct sync_ops mutex_sync_ops = { @@ -187,21 +187,23 @@ static void mutex_satisfied( struct sync *sync, struct object *obj, struct wait_ mutex->abandoned = 0; }
-static int mutex_signal( struct sync *sync, struct object *obj, unsigned int access ) +static int mutex_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops );
- if (!(access & SYNCHRONIZE)) + if (signal == SIGNAL_SELECT && !(access & SYNCHRONIZE)) { set_error( STATUS_ACCESS_DENIED ); return 0; } - if (!mutex->count || (mutex->owner != current)) + if (signal == SIGNAL_SELECT && (!mutex->count || (mutex->owner != current))) { set_error( STATUS_MUTANT_NOT_OWNED ); return 0; } + + assert( signal == SIGNAL_SELECT ); if (!--mutex->count) do_release( mutex ); return 1; } diff --git a/server/object.c b/server/object.c index 611fb1d9104..1704bea1b98 100644 --- a/server/object.c +++ b/server/object.c @@ -669,7 +669,7 @@ void no_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entr { }
-int no_signal( struct sync *sync, struct object *obj, unsigned int access ) +int no_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); return 0; diff --git a/server/object.h b/server/object.h index 265478bb459..e822106d86e 100644 --- a/server/object.h +++ b/server/object.h @@ -64,6 +64,8 @@ struct type_descr unsigned int handle_max; /* max count of handles of this type */ };
+#define SIGNAL_SELECT -1 /* sync is being signaled from select */ + /* operations valid on waitable objects */ struct sync_ops { @@ -79,8 +81,8 @@ struct sync_ops int (*signaled)(struct sync *,struct object *,struct wait_queue_entry *); /* wait satisfied */ void (*satisfied)(struct sync *,struct object *,struct wait_queue_entry *); - /* signal an object */ - int (*signal)(struct sync *,struct object *, unsigned int); + /* signal/reset a sync, signal is SIGNAL_SELECT when signaled from select */ + int (*signal)(struct sync *,struct object *,int,unsigned int); };
struct sync @@ -189,7 +191,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 int no_add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); extern void no_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); -extern int no_signal( struct sync *sync, struct object *obj, unsigned int access ); +extern int no_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ); extern void sync_destroy( struct sync *obj ); extern struct fd *no_get_fd( struct object *obj ); extern struct sync *no_get_sync( struct object *obj ); diff --git a/server/semaphore.c b/server/semaphore.c index 95f9a8f7fa3..1ebf7c435ea 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -63,7 +63,7 @@ static struct sync *semaphore_get_sync( struct object *obj ); static void semaphore_destroy( struct object *obj ); static int semaphore_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void semaphore_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); -static int semaphore_signal( struct sync *sync, struct object *obj, unsigned int access ); +static int semaphore_signal( struct sync *sync, struct object *obj, int signal, unsigned int access );
static const struct sync_ops semaphore_sync_ops = { @@ -179,16 +179,18 @@ static void semaphore_satisfied( struct sync *sync, struct object *obj, struct w sem->count--; }
-static int semaphore_signal( struct sync *sync, struct object *obj, unsigned int access ) +static int semaphore_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops );
- if (!(access & SEMAPHORE_MODIFY_STATE)) + if (signal == SIGNAL_SELECT && !(access & SEMAPHORE_MODIFY_STATE)) { set_error( STATUS_ACCESS_DENIED ); return 0; } + + assert( signal == SIGNAL_SELECT ); return release_semaphore( sem, 1, NULL ); }
diff --git a/server/thread.c b/server/thread.c index 8774917b7c9..0ded4076d82 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1266,7 +1266,7 @@ static int signal_object( obj_handle_t handle ) if (obj) { struct sync *sync = obj->ops->get_sync( obj ); - ret = sync->ops->signal( sync, obj, get_handle_access( current->process, handle ) ); + ret = sync->ops->signal( sync, obj, SIGNAL_SELECT, get_handle_access( current->process, handle ) ); release_object( obj ); } return ret;