Instead of https://gitlab.winehq.org/wine/wine/-/merge_requests/7815, for https://gitlab.winehq.org/wine/wine/-/merge_requests/7226, this only split the sync ops to a separate vtable and let objects delegate theirs to a separate object.
This starts using a event-like interface for most objects, leaving the decision regarding if/how to split sync themselves / integrate inproc syncs for later.
-- v10: server: Use an event sync for fd objects. server: Introduce a new event sync object. server: Redirect fd-based objects sync to the fd. server: Add an operation to retrieve an object sync. server: Move object grab/release out of (add|remove)_queue. server: Move signal access checks outside of the objects.
From: Rémi Bernon rbernon@codeweavers.com
--- server/event.c | 11 +++-------- server/mutex.c | 10 +++------- server/object.c | 3 +-- server/object.h | 5 +++-- server/semaphore.c | 11 +++-------- server/thread.c | 12 +++++++++++- 6 files changed, 24 insertions(+), 28 deletions(-)
diff --git a/server/event.c b/server/event.c index ad7c09acc99..579a43ab1fb 100644 --- a/server/event.c +++ b/server/event.c @@ -48,6 +48,7 @@ struct type_descr event_type = STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, EVENT_ALL_ACCESS }, + EVENT_MODIFY_STATE, /* signal access */ };
struct event @@ -61,7 +62,7 @@ struct event static void event_dump( struct object *obj, int verbose ); static int event_signaled( struct object *obj, struct wait_queue_entry *entry ); static void event_satisfied( struct object *obj, struct wait_queue_entry *entry ); -static int event_signal( struct object *obj, unsigned int access); +static int event_signal( struct object *obj ); static struct list *event_get_kernel_obj_list( struct object *obj );
static const struct object_ops event_ops = @@ -203,16 +204,10 @@ static void event_satisfied( struct object *obj, struct wait_queue_entry *entry if (!event->manual_reset) event->signaled = 0; }
-static int event_signal( struct object *obj, unsigned int access ) +static int event_signal( struct object *obj ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); - - if (!(access & EVENT_MODIFY_STATE)) - { - set_error( STATUS_ACCESS_DENIED ); - return 0; - } set_event( event ); return 1; } diff --git a/server/mutex.c b/server/mutex.c index af0efe72132..ec8644df6b3 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -48,6 +48,7 @@ struct type_descr mutex_type = STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, MUTANT_ALL_ACCESS }, + SYNCHRONIZE, /* signal access */ };
struct mutex @@ -63,7 +64,7 @@ static void mutex_dump( struct object *obj, int verbose ); static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry ); static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry ); static void mutex_destroy( struct object *obj ); -static int mutex_signal( struct object *obj, unsigned int access ); +static int mutex_signal( struct object *obj );
static const struct object_ops mutex_ops = { @@ -170,16 +171,11 @@ static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry mutex->abandoned = 0; }
-static int mutex_signal( struct object *obj, unsigned int access ) +static int mutex_signal( struct object *obj ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops );
- if (!(access & SYNCHRONIZE)) - { - set_error( STATUS_ACCESS_DENIED ); - return 0; - } if (!mutex->count || (mutex->owner != current)) { set_error( STATUS_MUTANT_NOT_OWNED ); diff --git a/server/object.c b/server/object.c index 7cb2ccbd93f..e8076da21eb 100644 --- a/server/object.c +++ b/server/object.c @@ -628,9 +628,8 @@ void no_satisfied( struct object *obj, struct wait_queue_entry *entry ) { }
-int no_signal( struct object *obj, unsigned int access ) +int no_signal( struct object *obj ) { - set_error( STATUS_OBJECT_TYPE_MISMATCH ); return 0; }
diff --git a/server/object.h b/server/object.h index 9211d2f9633..b2fd9887a41 100644 --- a/server/object.h +++ b/server/object.h @@ -56,6 +56,7 @@ struct type_descr struct unicode_str name; /* type name */ unsigned int valid_access; /* mask for valid access bits */ struct generic_map mapping; /* generic access mapping */ + unsigned int signal_access; /* mask for valid signal access */ unsigned int index; /* index in global array of types */ unsigned int obj_count; /* count of objects of this type */ unsigned int handle_count; /* count of handles of this type */ @@ -81,7 +82,7 @@ struct object_ops /* wait satisfied */ void (*satisfied)(struct object *,struct wait_queue_entry *); /* signal an object */ - int (*signal)(struct object *, unsigned int); + int (*signal)(struct object *); /* return an fd object that can be used to read/write from the object */ struct fd *(*get_fd)(struct object *); /* map access rights to the specific rights for this object */ @@ -168,7 +169,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 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 ); extern struct fd *no_get_fd( struct object *obj ); extern unsigned int default_map_access( struct object *obj, unsigned int access ); extern struct security_descriptor *default_get_sd( struct object *obj ); diff --git a/server/semaphore.c b/server/semaphore.c index 53b42a886df..b8d27afe3b7 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -48,6 +48,7 @@ struct type_descr semaphore_type = STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, SEMAPHORE_ALL_ACCESS }, + SEMAPHORE_MODIFY_STATE, /* signal access */ };
struct semaphore @@ -60,7 +61,7 @@ struct semaphore static void semaphore_dump( struct object *obj, int verbose ); static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry ); static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ); -static int semaphore_signal( struct object *obj, unsigned int access ); +static int semaphore_signal( struct object *obj );
static const struct object_ops semaphore_ops = { @@ -154,16 +155,10 @@ static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *en sem->count--; }
-static int semaphore_signal( struct object *obj, unsigned int access ) +static int semaphore_signal( struct object *obj ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); - - if (!(access & SEMAPHORE_MODIFY_STATE)) - { - set_error( STATUS_ACCESS_DENIED ); - return 0; - } return release_semaphore( sem, 1, NULL ); }
diff --git a/server/thread.c b/server/thread.c index 12b73d44353..acdb50d8c56 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1176,6 +1176,14 @@ static void thread_timeout( void *ptr ) wake_thread( thread ); }
+/* check if an event flag, a semaphore or a mutex can be signaled */ +static unsigned int check_signal_access( struct object *obj, unsigned int access ) +{ + if (!obj->ops->type->signal_access) return STATUS_OBJECT_TYPE_MISMATCH; + if (!(access & obj->ops->type->signal_access)) return STATUS_ACCESS_DENIED; + return STATUS_SUCCESS; +} + /* try signaling an event flag, a semaphore or a mutex */ static int signal_object( obj_handle_t handle ) { @@ -1185,7 +1193,9 @@ static int signal_object( obj_handle_t handle ) obj = get_handle_obj( current->process, handle, 0, NULL ); if (obj) { - ret = obj->ops->signal( obj, get_handle_access( current->process, handle )); + unsigned int status, access = get_handle_access( current->process, handle ); + if ((status = check_signal_access( obj, access ))) set_error( status ); + else ret = obj->ops->signal( obj ); release_object( obj ); } return ret;
From: Rémi Bernon rbernon@codeweavers.com
--- server/thread.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/server/thread.c b/server/thread.c index acdb50d8c56..e4a44784feb 100644 --- a/server/thread.c +++ b/server/thread.c @@ -914,8 +914,6 @@ int resume_thread( struct thread *thread ) /* add a thread to an object wait queue; return 1 if OK, 0 on error */ int add_queue( struct object *obj, struct wait_queue_entry *entry ) { - grab_object( obj ); - entry->obj = obj; list_add_tail( &obj->wait_queue, &entry->entry ); return 1; } @@ -924,7 +922,6 @@ int add_queue( struct object *obj, struct wait_queue_entry *entry ) void remove_queue( struct object *obj, struct wait_queue_entry *entry ) { list_remove( &entry->entry ); - release_object( obj ); }
struct thread *get_wait_queue_thread( struct wait_queue_entry *entry ) @@ -979,7 +976,11 @@ static unsigned int end_wait( struct thread *thread, unsigned int status ) if (wait->abandoned) status += STATUS_ABANDONED_WAIT_0; } for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) + { entry->obj->ops->remove_queue( entry->obj, entry ); + release_object( entry->obj ); + entry->obj = NULL; + } if (wait->user) remove_timeout_user( wait->user ); free( wait ); return status; @@ -1016,6 +1017,7 @@ static int wait_on( const union select_op *select_op, unsigned int count, struct return 0; }
+ grab_object( (entry->obj = obj) ); if (obj == (struct object *)current->queue) idle = 1; }
From: Rémi Bernon rbernon@codeweavers.com
--- server/async.c | 2 ++ server/atom.c | 1 + server/change.c | 1 + server/clipboard.c | 1 + server/completion.c | 2 ++ server/console.c | 7 ++++++ server/debugger.c | 2 ++ server/device.c | 4 ++++ server/directory.c | 2 ++ server/event.c | 2 ++ server/fd.c | 4 ++++ server/file.c | 1 + server/handle.c | 1 + server/hook.c | 1 + server/mailslot.c | 4 ++++ server/mapping.c | 3 +++ server/mutex.c | 1 + server/named_pipe.c | 6 +++++ server/object.c | 7 ++++++ server/object.h | 4 ++++ server/process.c | 3 +++ server/queue.c | 2 ++ server/registry.c | 1 + server/request.c | 1 + server/semaphore.c | 1 + server/serial.c | 1 + server/signal.c | 1 + server/sock.c | 3 +++ server/symlink.c | 1 + server/thread.c | 55 +++++++++++++++++++++++++++++++++++++++------ server/timer.c | 1 + server/token.c | 1 + server/window.c | 1 + server/winstation.c | 2 ++ 34 files changed, 123 insertions(+), 7 deletions(-)
diff --git a/server/async.c b/server/async.c index d2d929c9709..1ed241dcb65 100644 --- a/server/async.c +++ b/server/async.c @@ -81,6 +81,7 @@ static const struct object_ops async_ops = async_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -701,6 +702,7 @@ static const struct object_ops iosb_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/atom.c b/server/atom.c index ff0799f5880..d93f1568588 100644 --- a/server/atom.c +++ b/server/atom.c @@ -82,6 +82,7 @@ static const struct object_ops atom_table_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/change.c b/server/change.c index f42ce066340..a6f367b8075 100644 --- a/server/change.c +++ b/server/change.c @@ -115,6 +115,7 @@ static const struct object_ops dir_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ dir_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ dir_get_sd, /* get_sd */ dir_set_sd, /* set_sd */ diff --git a/server/clipboard.c b/server/clipboard.c index 91f159bc7c9..59a50354b48 100644 --- a/server/clipboard.c +++ b/server/clipboard.c @@ -79,6 +79,7 @@ static const struct object_ops clipboard_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/completion.c b/server/completion.c index 99680ae0680..fd623b36d5a 100644 --- a/server/completion.c +++ b/server/completion.c @@ -95,6 +95,7 @@ static const struct object_ops completion_wait_ops = completion_wait_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -169,6 +170,7 @@ static const struct object_ops completion_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/console.c b/server/console.c index de6f4e73e31..aa7ec863605 100644 --- a/server/console.c +++ b/server/console.c @@ -87,6 +87,7 @@ static const struct object_ops console_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ console_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -164,6 +165,7 @@ static const struct object_ops console_server_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ console_server_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -233,6 +235,7 @@ static const struct object_ops screen_buffer_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ screen_buffer_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -282,6 +285,7 @@ static const struct object_ops console_device_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -321,6 +325,7 @@ static const struct object_ops console_input_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ console_input_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -380,6 +385,7 @@ static const struct object_ops console_output_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ console_output_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -438,6 +444,7 @@ static const struct object_ops console_connection_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ console_connection_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/debugger.c b/server/debugger.c index 39a740e07e5..43d01fbf246 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -89,6 +89,7 @@ static const struct object_ops debug_event_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -117,6 +118,7 @@ static const struct object_ops debug_obj_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/device.c b/server/device.c index 2e3c5eb5bff..d4cdacf7132 100644 --- a/server/device.c +++ b/server/device.c @@ -69,6 +69,7 @@ static const struct object_ops irp_call_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -109,6 +110,7 @@ static const struct object_ops device_manager_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -166,6 +168,7 @@ static const struct object_ops device_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -218,6 +221,7 @@ static const struct object_ops device_file_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ device_file_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/directory.c b/server/directory.c index fd689c561bc..c8dc3d1901d 100644 --- a/server/directory.c +++ b/server/directory.c @@ -72,6 +72,7 @@ static const struct object_ops object_type_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -122,6 +123,7 @@ static const struct object_ops directory_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/event.c b/server/event.c index 579a43ab1fb..ce264f10924 100644 --- a/server/event.c +++ b/server/event.c @@ -76,6 +76,7 @@ static const struct object_ops event_ops = event_satisfied, /* satisfied */ event_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -123,6 +124,7 @@ static const struct object_ops keyed_event_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/fd.c b/server/fd.c index bb0e90d99d0..f6d232edd82 100644 --- a/server/fd.c +++ b/server/fd.c @@ -170,6 +170,7 @@ static const struct object_ops fd_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -211,6 +212,7 @@ static const struct object_ops device_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -251,6 +253,7 @@ static const struct object_ops inode_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -293,6 +296,7 @@ static const struct object_ops file_lock_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/file.c b/server/file.c index 8f6566a0077..4b94a75823a 100644 --- a/server/file.c +++ b/server/file.c @@ -97,6 +97,7 @@ static const struct object_ops file_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ file_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ file_get_sd, /* get_sd */ file_set_sd, /* set_sd */ diff --git a/server/handle.c b/server/handle.c index 44232daf48c..e4e843f4e39 100644 --- a/server/handle.c +++ b/server/handle.c @@ -129,6 +129,7 @@ static const struct object_ops handle_table_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/hook.c b/server/hook.c index 4c55c565968..7ba1f3ea9bf 100644 --- a/server/hook.c +++ b/server/hook.c @@ -84,6 +84,7 @@ static const struct object_ops hook_table_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/mailslot.c b/server/mailslot.c index 420e3d67345..15b9909caf2 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -85,6 +85,7 @@ static const struct object_ops mailslot_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ mailslot_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ mailslot_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -146,6 +147,7 @@ static const struct object_ops mail_writer_ops = NULL, /* satisfied */ no_signal, /* signal */ mail_writer_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ mail_writer_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -211,6 +213,7 @@ static const struct object_ops mailslot_device_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -241,6 +244,7 @@ static const struct object_ops mailslot_device_file_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ mailslot_device_file_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/mapping.c b/server/mapping.c index 7edadcbbeda..c3f57b6394c 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -70,6 +70,7 @@ static const struct object_ops ranges_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -106,6 +107,7 @@ static const struct object_ops shared_map_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -179,6 +181,7 @@ static const struct object_ops mapping_ops = NULL, /* satisfied */ no_signal, /* signal */ mapping_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/mutex.c b/server/mutex.c index ec8644df6b3..3633892a016 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -77,6 +77,7 @@ static const struct object_ops mutex_ops = mutex_satisfied, /* satisfied */ mutex_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/named_pipe.c b/server/named_pipe.c index f1263013bf1..d83428233f4 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -122,6 +122,7 @@ static const struct object_ops named_pipe_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ named_pipe_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -170,6 +171,7 @@ static const struct object_ops pipe_server_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ pipe_end_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ pipe_end_get_sd, /* get_sd */ pipe_end_set_sd, /* set_sd */ @@ -214,6 +216,7 @@ static const struct object_ops pipe_client_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ pipe_end_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ pipe_end_get_sd, /* get_sd */ pipe_end_set_sd, /* set_sd */ @@ -262,6 +265,7 @@ static const struct object_ops named_pipe_device_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -293,6 +297,7 @@ static const struct object_ops named_pipe_device_file_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ named_pipe_device_file_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -343,6 +348,7 @@ static const struct object_ops named_pipe_dir_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ named_pipe_dir_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/object.c b/server/object.c index e8076da21eb..1e5a5ef36f6 100644 --- a/server/object.c +++ b/server/object.c @@ -111,6 +111,7 @@ static const struct object_ops apc_reserve_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -135,6 +136,7 @@ static const struct object_ops completion_reserve_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -639,6 +641,11 @@ struct fd *no_get_fd( struct object *obj ) return NULL; }
+struct object *default_get_sync( struct object *obj ) +{ + return grab_object( obj ); +} + unsigned int default_map_access( struct object *obj, unsigned int access ) { return map_access( access, &obj->ops->type->mapping ); diff --git a/server/object.h b/server/object.h index b2fd9887a41..4fb0d0a9637 100644 --- a/server/object.h +++ b/server/object.h @@ -85,6 +85,8 @@ struct object_ops int (*signal)(struct object *); /* return an fd object that can be used to read/write from the object */ struct fd *(*get_fd)(struct object *); + /* return a sync that can be used to wait/signal the object */ + struct object *(*get_sync)(struct object *); /* map access rights to the specific rights for this object */ unsigned int (*map_access)(struct object *, unsigned int); /* returns the security descriptor of the object */ @@ -171,6 +173,8 @@ extern int no_add_queue( 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 ); extern struct fd *no_get_fd( struct object *obj ); +extern struct object *default_get_sync( struct object *obj ); +static inline struct object *get_obj_sync( struct object *obj ) { return obj->ops->get_sync( obj ); } extern unsigned int default_map_access( struct object *obj, unsigned int access ); extern struct security_descriptor *default_get_sd( struct object *obj ); extern int default_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info ); diff --git a/server/process.c b/server/process.c index 3b9f311e337..b169b412253 100644 --- a/server/process.c +++ b/server/process.c @@ -109,6 +109,7 @@ static const struct object_ops process_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ process_map_access, /* map_access */ process_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -160,6 +161,7 @@ static const struct object_ops startup_info_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -221,6 +223,7 @@ static const struct object_ops job_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/queue.c b/server/queue.c index 10c8b70f659..3b0bd1826ef 100644 --- a/server/queue.c +++ b/server/queue.c @@ -168,6 +168,7 @@ static const struct object_ops msg_queue_ops = msg_queue_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -205,6 +206,7 @@ static const struct object_ops thread_input_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/registry.c b/server/registry.c index dba7e0f8d7b..36e95b48f15 100644 --- a/server/registry.c +++ b/server/registry.c @@ -183,6 +183,7 @@ static const struct object_ops key_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ key_map_access, /* map_access */ key_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/request.c b/server/request.c index 2254315b79e..835ea30cec3 100644 --- a/server/request.c +++ b/server/request.c @@ -92,6 +92,7 @@ static const struct object_ops master_socket_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/semaphore.c b/server/semaphore.c index b8d27afe3b7..09e8e65ea56 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -74,6 +74,7 @@ static const struct object_ops semaphore_ops = semaphore_satisfied, /* satisfied */ semaphore_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/serial.c b/server/serial.c index 209f2e9174e..fc0939e402b 100644 --- a/server/serial.c +++ b/server/serial.c @@ -94,6 +94,7 @@ static const struct object_ops serial_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ serial_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/signal.c b/server/signal.c index 19b76d44c16..078951af6e4 100644 --- a/server/signal.c +++ b/server/signal.c @@ -65,6 +65,7 @@ static const struct object_ops handler_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/sock.c b/server/sock.c index e064f867ff4..0dd0f308337 100644 --- a/server/sock.c +++ b/server/sock.c @@ -489,6 +489,7 @@ static const struct object_ops sock_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ sock_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -3698,6 +3699,7 @@ static const struct object_ops ifchange_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ ifchange_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -3919,6 +3921,7 @@ static const struct object_ops socket_device_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/symlink.c b/server/symlink.c index 55638a502bd..238dcfad1c7 100644 --- a/server/symlink.c +++ b/server/symlink.c @@ -74,6 +74,7 @@ static const struct object_ops symlink_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/thread.c b/server/thread.c index e4a44784feb..6f0d506214e 100644 --- a/server/thread.c +++ b/server/thread.c @@ -109,6 +109,7 @@ static const struct object_ops thread_apc_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -151,6 +152,7 @@ static const struct object_ops context_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -200,6 +202,7 @@ static const struct object_ops thread_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ thread_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -949,6 +952,44 @@ void set_wait_status( struct wait_queue_entry *entry, int status ) entry->wait->status = status; }
+static void object_sync_satisfied( struct object *obj, struct wait_queue_entry *entry ) +{ + struct object *sync = get_obj_sync( obj ); + sync->ops->satisfied( sync, entry ); + release_object( sync ); +} + +static void object_sync_remove_queue( struct object *obj, struct wait_queue_entry *entry ) +{ + struct object *sync = get_obj_sync( obj ); + sync->ops->remove_queue( sync, entry ); + release_object( sync ); +} + +static int object_sync_add_queue( struct object *obj, struct wait_queue_entry *entry ) +{ + struct object *sync = get_obj_sync( obj ); + int ret = sync->ops->add_queue( sync, entry ); + release_object( sync ); + return ret; +} + +static int object_sync_signaled( struct object *obj, struct wait_queue_entry *entry ) +{ + struct object *sync = get_obj_sync( obj ); + int ret = sync->ops->signaled( sync, entry ); + release_object( sync ); + return ret; +} + +static int object_sync_signal( struct object *obj ) +{ + struct object *sync = get_obj_sync( obj ); + int ret = sync->ops->signal( sync ); + release_object( sync ); + return ret; +} + /* finish waiting */ static unsigned int end_wait( struct thread *thread, unsigned int status ) { @@ -965,19 +1006,19 @@ static unsigned int end_wait( struct thread *thread, unsigned int status ) if (wait->select == SELECT_WAIT_ALL) { for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) - entry->obj->ops->satisfied( entry->obj, entry ); + object_sync_satisfied( entry->obj, entry ); } else { entry = wait->queues + status; - entry->obj->ops->satisfied( entry->obj, entry ); + object_sync_satisfied( entry->obj, entry ); } status = wait->status; if (wait->abandoned) status += STATUS_ABANDONED_WAIT_0; } for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) { - entry->obj->ops->remove_queue( entry->obj, entry ); + object_sync_remove_queue( entry->obj, entry ); release_object( entry->obj ); entry->obj = NULL; } @@ -1010,7 +1051,7 @@ static int wait_on( const union select_op *select_op, unsigned int count, struct { struct object *obj = objects[i]; entry->wait = wait; - if (!obj->ops->add_queue( obj, entry )) + if (!object_sync_add_queue( obj, entry )) { wait->count = i; end_wait( current, get_error() ); @@ -1065,13 +1106,13 @@ 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, entry ); + not_ok |= !object_sync_signaled( entry->obj, entry ); if (!not_ok) return STATUS_WAIT_0; } else { for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) - if (entry->obj->ops->signaled( entry->obj, entry )) return i; + if (object_sync_signaled( entry->obj, entry )) return i; }
if ((wait->flags & SELECT_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC; @@ -1197,7 +1238,7 @@ static int signal_object( obj_handle_t handle ) { unsigned int status, access = get_handle_access( current->process, handle ); if ((status = check_signal_access( obj, access ))) set_error( status ); - else ret = obj->ops->signal( obj ); + else ret = object_sync_signal( obj ); release_object( obj ); } return ret; diff --git a/server/timer.c b/server/timer.c index b0b6ec81535..4ad4ca19072 100644 --- a/server/timer.c +++ b/server/timer.c @@ -79,6 +79,7 @@ static const struct object_ops timer_ops = timer_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/token.c b/server/token.c index 3cdb9e5be5f..5ce7298211e 100644 --- a/server/token.c +++ b/server/token.c @@ -148,6 +148,7 @@ static const struct object_ops token_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ token_set_sd, /* set_sd */ diff --git a/server/window.c b/server/window.c index e2e9d5cc485..6b45633f66d 100644 --- a/server/window.c +++ b/server/window.c @@ -111,6 +111,7 @@ static const struct object_ops window_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/winstation.c b/server/winstation.c index b3746090ccf..bb5596f9a03 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -79,6 +79,7 @@ static const struct object_ops winstation_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -119,6 +120,7 @@ static const struct object_ops desktop_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */
From: Rémi Bernon rbernon@codeweavers.com
--- server/change.c | 12 ++++++------ server/device.c | 12 ++++++------ server/fd.c | 26 +++++++++++++++--------- server/file.c | 12 ++++++------ server/file.h | 2 +- server/mailslot.c | 24 +++++++++++------------ server/named_pipe.c | 48 ++++++++++++++++++++++----------------------- server/serial.c | 12 ++++++------ server/sock.c | 12 ++++++------ 9 files changed, 84 insertions(+), 76 deletions(-)
diff --git a/server/change.c b/server/change.c index a6f367b8075..1f451be64f0 100644 --- a/server/change.c +++ b/server/change.c @@ -109,13 +109,13 @@ static const struct object_ops dir_ops = sizeof(struct dir), /* size */ &file_type, /* type */ dir_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ dir_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ dir_get_sd, /* get_sd */ dir_set_sd, /* set_sd */ diff --git a/server/device.c b/server/device.c index d4cdacf7132..5612f425207 100644 --- a/server/device.c +++ b/server/device.c @@ -215,13 +215,13 @@ static const struct object_ops device_file_ops = sizeof(struct device_file), /* size */ &file_type, /* type */ device_file_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ device_file_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/fd.c b/server/fd.c index f6d232edd82..94fa3e2dae7 100644 --- a/server/fd.c +++ b/server/fd.c @@ -157,6 +157,7 @@ struct fd };
static void fd_dump( struct object *obj, int verbose ); +static int fd_signaled( struct object *obj, struct wait_queue_entry *entry ); static void fd_destroy( struct object *obj );
static const struct object_ops fd_ops = @@ -164,10 +165,10 @@ static const struct object_ops fd_ops = sizeof(struct fd), /* size */ &no_type, /* type */ fd_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ + add_queue, /* add_queue */ + remove_queue, /* remove_queue */ + fd_signaled, /* signaled */ + no_satisfied, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ default_get_sync, /* get_sync */ @@ -2156,7 +2157,7 @@ void set_fd_signaled( struct fd *fd, int signaled ) { if (fd->comp_flags & FILE_SKIP_SET_EVENT_ON_HANDLE) return; fd->signaled = signaled; - if (signaled) wake_up( fd->user, 0 ); + if (signaled) wake_up( &fd->obj, 0 ); }
/* check if events are pending and if yes return which one(s) */ @@ -2173,13 +2174,20 @@ int check_fd_events( struct fd *fd, int events ) return pfd.revents; }
-/* default signaled() routine for objects that poll() on an fd */ -int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int fd_signaled( struct object *obj, struct wait_queue_entry *entry ) +{ + struct fd *fd = (struct fd *)obj; + assert( obj->ops == &fd_ops ); + return fd->signaled; +} + +/* default get_sync() routine for objects that poll() on an fd */ +struct object *default_fd_get_sync( struct object *obj ) { struct fd *fd = get_obj_fd( obj ); - int ret = fd->signaled; + struct object *sync = get_obj_sync( &fd->obj ); release_object( fd ); - return ret; + return sync; }
int default_fd_get_poll_events( struct fd *fd ) diff --git a/server/file.c b/server/file.c index 4b94a75823a..b3840381d06 100644 --- a/server/file.c +++ b/server/file.c @@ -91,13 +91,13 @@ static const struct object_ops file_ops = sizeof(struct file), /* size */ &file_type, /* type */ file_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ file_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ file_get_sd, /* get_sd */ file_set_sd, /* set_sd */ diff --git a/server/file.h b/server/file.h index 4510a8b4e88..03582434776 100644 --- a/server/file.h +++ b/server/file.h @@ -108,7 +108,7 @@ extern void set_fd_signaled( struct fd *fd, int signaled ); extern char *dup_fd_name( struct fd *root, const char *name ) __WINE_DEALLOC(free) __WINE_MALLOC; extern void get_nt_name( struct fd *fd, struct unicode_str *name );
-extern int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry ); +extern struct object *default_fd_get_sync( struct object *obj ); extern int default_fd_get_poll_events( struct fd *fd ); extern void default_poll_event( struct fd *fd, int event ); extern void fd_cancel_async( struct fd *fd, struct async *async ); diff --git a/server/mailslot.c b/server/mailslot.c index 15b9909caf2..20a7df1b1a4 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -79,13 +79,13 @@ static const struct object_ops mailslot_ops = sizeof(struct mailslot), /* size */ &file_type, /* type */ mailslot_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ mailslot_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ mailslot_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -238,13 +238,13 @@ static const struct object_ops mailslot_device_file_ops = sizeof(struct mailslot_device_file), /* size */ &file_type, /* type */ mailslot_device_file_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ mailslot_device_file_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/named_pipe.c b/server/named_pipe.c index d83428233f4..97876128c6b 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -165,13 +165,13 @@ static const struct object_ops pipe_server_ops = sizeof(struct pipe_server), /* size */ &file_type, /* type */ pipe_server_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ pipe_end_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ pipe_end_get_sd, /* get_sd */ pipe_end_set_sd, /* set_sd */ @@ -210,13 +210,13 @@ static const struct object_ops pipe_client_ops = sizeof(struct pipe_end), /* size */ &file_type, /* type */ pipe_client_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ pipe_end_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ pipe_end_get_sd, /* get_sd */ pipe_end_set_sd, /* set_sd */ @@ -291,13 +291,13 @@ static const struct object_ops named_pipe_device_file_ops = sizeof(struct named_pipe_device_file), /* size */ &file_type, /* type */ named_pipe_device_file_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ named_pipe_device_file_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -342,13 +342,13 @@ static const struct object_ops named_pipe_dir_ops = sizeof(struct named_pipe_device_file), /* size */ &file_type, /* type */ named_pipe_dir_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ named_pipe_dir_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/serial.c b/server/serial.c index fc0939e402b..40150080ce1 100644 --- a/server/serial.c +++ b/server/serial.c @@ -88,13 +88,13 @@ static const struct object_ops serial_ops = sizeof(struct serial), /* size */ &file_type, /* type */ serial_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ serial_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ diff --git a/server/sock.c b/server/sock.c index 0dd0f308337..b9b3743e030 100644 --- a/server/sock.c +++ b/server/sock.c @@ -483,13 +483,13 @@ static const struct object_ops sock_ops = sizeof(struct sock), /* size */ &file_type, /* type */ sock_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ sock_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */
From: Rémi Bernon rbernon@codeweavers.com
--- server/event.c | 183 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 137 insertions(+), 46 deletions(-)
diff --git a/server/event.c b/server/event.c index ce264f10924..b954af8bd8b 100644 --- a/server/event.c +++ b/server/event.c @@ -51,32 +51,127 @@ struct type_descr event_type = EVENT_MODIFY_STATE, /* signal access */ };
+struct event_sync +{ + struct object obj; /* object header */ + unsigned int manual : 1; /* is it a manual reset event? */ + unsigned int signaled : 1; /* event has been signaled */ +}; + +static void event_sync_dump( struct object *obj, int verbose ); +static int event_sync_signaled( struct object *obj, struct wait_queue_entry *entry ); +static void event_sync_satisfied( struct object *obj, struct wait_queue_entry *entry ); +static int event_sync_signal( struct object *obj ); + +static const struct object_ops event_sync_ops = +{ + sizeof(struct event_sync), /* size */ + &no_type, /* type */ + event_sync_dump, /* dump */ + add_queue, /* add_queue */ + remove_queue, /* remove_queue */ + event_sync_signaled, /* signaled */ + event_sync_satisfied, /* satisfied */ + event_sync_signal, /* signal */ + no_get_fd, /* get_fd */ + default_get_sync, /* get_sync */ + default_map_access, /* map_access */ + default_get_sd, /* get_sd */ + default_set_sd, /* set_sd */ + default_get_full_name, /* get_full_name */ + no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_kernel_obj_list, /* get_kernel_obj_list */ + no_close_handle, /* close_handle */ + no_destroy /* destroy */ +}; + +static struct object *create_event_sync( int manual, int signaled ) +{ + struct event_sync *event; + + if (!(event = alloc_object( &event_sync_ops ))) return NULL; + event->manual = manual; + event->signaled = signaled; + + return &event->obj; +} + +static void signal_sync( struct object *obj ) +{ + struct event_sync *event = (struct event_sync *)obj; + assert( obj->ops == &event_sync_ops ); + + event->signaled = 1; + /* wake up all waiters if manual reset, a single one otherwise */ + wake_up( &event->obj, !event->manual ); +} + +static void reset_sync( struct object *obj ) +{ + struct event_sync *event = (struct event_sync *)obj; + assert( obj->ops == &event_sync_ops ); + + event->signaled = 0; +} + +static void event_sync_dump( struct object *obj, int verbose ) +{ + struct event_sync *event = (struct event_sync *)obj; + assert( obj->ops == &event_sync_ops ); + fprintf( stderr, "Event manual=%d signaled=%d\n", + event->manual, event->signaled ); +} + +static int event_sync_signaled( struct object *obj, struct wait_queue_entry *entry ) +{ + struct event_sync *event = (struct event_sync *)obj; + assert( obj->ops == &event_sync_ops ); + return event->signaled; +} + +static void event_sync_satisfied( struct object *obj, struct wait_queue_entry *entry ) +{ + struct event_sync *event = (struct event_sync *)obj; + assert( obj->ops == &event_sync_ops ); + /* Reset if it's an auto-reset event */ + if (!event->manual) event->signaled = 0; +} + +static int event_sync_signal( struct object *obj ) +{ + struct event_sync *event = (struct event_sync *)obj; + assert( obj->ops == &event_sync_ops ); + signal_sync( &event->obj ); + return 1; +} + struct event { struct object obj; /* object header */ + struct object *sync; /* event sync object */ struct list kernel_object; /* list of kernel object pointers */ - int manual_reset; /* is it a manual reset event? */ - int signaled; /* event has been signaled */ };
static void event_dump( struct object *obj, int verbose ); -static int event_signaled( struct object *obj, struct wait_queue_entry *entry ); -static void event_satisfied( struct object *obj, struct wait_queue_entry *entry ); -static int event_signal( struct object *obj ); +static struct object *event_get_sync( struct object *obj ); static struct list *event_get_kernel_obj_list( struct object *obj ); +static void event_destroy( struct object *obj );
static const struct object_ops event_ops = { sizeof(struct event), /* size */ &event_type, /* type */ event_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - event_signaled, /* signaled */ - event_satisfied, /* satisfied */ - event_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ no_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + event_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -87,7 +182,7 @@ static const struct object_ops event_ops = no_open_file, /* open_file */ event_get_kernel_obj_list, /* get_kernel_obj_list */ no_close_handle, /* close_handle */ - no_destroy /* destroy */ + event_destroy, /* destroy */ };
@@ -150,9 +245,14 @@ struct event *create_event( struct object *root, const struct unicode_str *name, if (get_error() != STATUS_OBJECT_NAME_EXISTS) { /* initialize it if it didn't already exist */ + event->sync = NULL; list_init( &event->kernel_object ); - event->manual_reset = manual_reset; - event->signaled = initial_state; + + if (!(event->sync = create_event_sync( manual_reset, initial_state ))) + { + release_object( event ); + return NULL; + } } } return event; @@ -163,61 +263,42 @@ struct event *get_event_obj( struct process *process, obj_handle_t handle, unsig return (struct event *)get_handle_obj( process, handle, access, &event_ops ); }
-static void pulse_event( struct event *event ) -{ - event->signaled = 1; - /* wake up all waiters if manual reset, a single one otherwise */ - wake_up( &event->obj, !event->manual_reset ); - event->signaled = 0; -} - void set_event( struct event *event ) { - event->signaled = 1; - /* wake up all waiters if manual reset, a single one otherwise */ - wake_up( &event->obj, !event->manual_reset ); + signal_sync( event->sync ); }
void reset_event( struct event *event ) { - event->signaled = 0; + reset_sync( event->sync ); }
static void event_dump( struct object *obj, int verbose ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); - fprintf( stderr, "Event manual=%d signaled=%d\n", - event->manual_reset, event->signaled ); + event->sync->ops->dump( event->sync, verbose ); }
-static int event_signaled( struct object *obj, struct wait_queue_entry *entry ) +static struct object *event_get_sync( struct object *obj ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); - return event->signaled; + return grab_object( event->sync ); }
-static void event_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static struct list *event_get_kernel_obj_list( struct object *obj ) { 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 &event->kernel_object; }
-static int event_signal( struct object *obj ) +static void event_destroy( struct object *obj ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); - set_event( event ); - return 1; -}
-static struct list *event_get_kernel_obj_list( struct object *obj ) -{ - struct event *event = (struct event *)obj; - return &event->kernel_object; + if (event->sync) release_object( event->sync ); }
struct keyed_event *create_keyed_event( struct object *root, const struct unicode_str *name, @@ -310,14 +391,21 @@ DECL_HANDLER(open_event) /* do an event operation */ DECL_HANDLER(event_op) { + struct event_sync *sync; struct event *event;
if (!(event = get_event_obj( current->process, req->handle, EVENT_MODIFY_STATE ))) return; - reply->state = event->signaled; + sync = (struct event_sync *)event->sync; + assert( event->sync->ops == &event_sync_ops ); + + reply->state = sync->signaled; switch(req->op) { case PULSE_EVENT: - pulse_event( event ); + sync->signaled = 1; + /* wake up all waiters if manual reset, a single one otherwise */ + wake_up( &sync->obj, !sync->manual ); + sync->signaled = 0; break; case SET_EVENT: set_event( event ); @@ -335,12 +423,15 @@ DECL_HANDLER(event_op) /* return details about the event */ DECL_HANDLER(query_event) { + struct event_sync *sync; struct event *event;
if (!(event = get_event_obj( current->process, req->handle, EVENT_QUERY_STATE ))) return; + sync = (struct event_sync *)event->sync; + assert( event->sync->ops == &event_sync_ops );
- reply->manual_reset = event->manual_reset; - reply->state = event->signaled; + reply->manual_reset = sync->manual; + reply->state = sync->signaled;
release_object( event ); }
From: Rémi Bernon rbernon@codeweavers.com
--- server/event.c | 6 +++--- server/fd.c | 56 ++++++++++++++++++++++++++++--------------------- server/object.h | 4 ++++ 3 files changed, 39 insertions(+), 27 deletions(-)
diff --git a/server/event.c b/server/event.c index b954af8bd8b..d7a9af94974 100644 --- a/server/event.c +++ b/server/event.c @@ -88,7 +88,7 @@ static const struct object_ops event_sync_ops = no_destroy /* destroy */ };
-static struct object *create_event_sync( int manual, int signaled ) +struct object *create_event_sync( int manual, int signaled ) { struct event_sync *event;
@@ -99,7 +99,7 @@ static struct object *create_event_sync( int manual, int signaled ) return &event->obj; }
-static void signal_sync( struct object *obj ) +void signal_sync( struct object *obj ) { struct event_sync *event = (struct event_sync *)obj; assert( obj->ops == &event_sync_ops ); @@ -109,7 +109,7 @@ static void signal_sync( struct object *obj ) wake_up( &event->obj, !event->manual ); }
-static void reset_sync( struct object *obj ) +void reset_sync( struct object *obj ) { struct event_sync *event = (struct event_sync *)obj; assert( obj->ops == &event_sync_ops ); diff --git a/server/fd.c b/server/fd.c index 94fa3e2dae7..faf617cabad 100644 --- a/server/fd.c +++ b/server/fd.c @@ -129,6 +129,7 @@ struct fd { struct object obj; /* object header */ const struct fd_ops *fd_ops; /* file descriptor operations */ + struct object *sync; /* sync object for wait/signal */ struct inode *inode; /* inode that this fd belongs to */ struct list inode_entry; /* entry in inode fd list */ struct closed_fd *closed; /* structure to store the unix fd at destroy time */ @@ -145,7 +146,6 @@ struct fd int unix_fd; /* unix file descriptor */ unsigned int no_fd_status;/* status to return when unix_fd is -1 */ unsigned int cacheable :1;/* can the fd be cached on the client side? */ - unsigned int signaled :1; /* is the fd signaled? */ unsigned int fs_locks :1; /* can we use filesystem locks for this fd? */ int poll_index; /* index of fd in poll array */ struct async_queue read_q; /* async readers of this fd */ @@ -157,7 +157,7 @@ struct fd };
static void fd_dump( struct object *obj, int verbose ); -static int fd_signaled( struct object *obj, struct wait_queue_entry *entry ); +static struct object *fd_get_sync( struct object *obj ); static void fd_destroy( struct object *obj );
static const struct object_ops fd_ops = @@ -165,13 +165,13 @@ static const struct object_ops fd_ops = sizeof(struct fd), /* size */ &no_type, /* type */ fd_dump, /* dump */ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ + NULL, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* signal */ no_get_fd, /* get_fd */ - default_get_sync, /* get_sync */ + fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -1565,6 +1565,12 @@ static void fd_dump( struct object *obj, int verbose ) fprintf( stderr, "\n" ); }
+static struct object *fd_get_sync( struct object *obj ) +{ + struct fd *fd = (struct fd *)obj; + return grab_object( fd->sync ); +} + static void fd_destroy( struct object *obj ) { struct fd *fd = (struct fd *)obj; @@ -1589,6 +1595,7 @@ static void fd_destroy( struct object *obj ) if (fd->unix_fd != -1) close( fd->unix_fd ); free( fd->unix_name ); } + if (fd->sync) release_object( fd->sync ); }
/* check if the desired access is possible without violating */ @@ -1689,6 +1696,7 @@ static struct fd *alloc_fd_object(void) if (!fd) return NULL;
fd->fd_ops = NULL; + fd->sync = NULL; fd->user = NULL; fd->inode = NULL; fd->closed = NULL; @@ -1702,7 +1710,6 @@ static struct fd *alloc_fd_object(void) fd->nt_name = NULL; fd->nt_namelen = 0; fd->cacheable = 0; - fd->signaled = 1; fd->fs_locks = 1; fd->poll_index = -1; fd->completion = NULL; @@ -1713,12 +1720,14 @@ static struct fd *alloc_fd_object(void) list_init( &fd->inode_entry ); list_init( &fd->locks );
- if ((fd->poll_index = add_poll_user( fd )) == -1) - { - release_object( fd ); - return NULL; - } + if (!(fd->sync = create_event_sync( 1, 1 ))) goto error; + if ((fd->poll_index = add_poll_user( fd )) == -1) goto error; + return fd; + +error: + release_object( fd ); + return NULL; }
/* allocate a pseudo fd object, for objects that need to behave like files but don't have a unix fd */ @@ -1729,6 +1738,7 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use if (!fd) return NULL;
fd->fd_ops = fd_user_ops; + fd->sync = NULL; fd->user = user; fd->inode = NULL; fd->closed = NULL; @@ -1742,7 +1752,6 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use fd->nt_namelen = 0; fd->unix_fd = -1; fd->cacheable = 0; - fd->signaled = 1; fd->fs_locks = 0; fd->poll_index = -1; fd->completion = NULL; @@ -1753,6 +1762,12 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use init_async_queue( &fd->wait_q ); list_init( &fd->inode_entry ); list_init( &fd->locks ); + + if (!(fd->sync = create_event_sync( 1, 1 ))) + { + release_object( fd ); + return NULL; + } return fd; }
@@ -2156,8 +2171,8 @@ int is_fd_removable( struct fd *fd ) void set_fd_signaled( struct fd *fd, int signaled ) { if (fd->comp_flags & FILE_SKIP_SET_EVENT_ON_HANDLE) return; - fd->signaled = signaled; - if (signaled) wake_up( &fd->obj, 0 ); + if (signaled) signal_sync( fd->sync ); + else reset_sync( fd->sync ); }
/* check if events are pending and if yes return which one(s) */ @@ -2174,13 +2189,6 @@ int check_fd_events( struct fd *fd, int events ) return pfd.revents; }
-static int fd_signaled( struct object *obj, struct wait_queue_entry *entry ) -{ - struct fd *fd = (struct fd *)obj; - assert( obj->ops == &fd_ops ); - return fd->signaled; -} - /* default get_sync() routine for objects that poll() on an fd */ struct object *default_fd_get_sync( struct object *obj ) { diff --git a/server/object.h b/server/object.h index 4fb0d0a9637..d0a5929cbc8 100644 --- a/server/object.h +++ b/server/object.h @@ -219,6 +219,10 @@ static inline void *mem_append( void *ptr, const void *src, data_size_t len ) struct event; struct keyed_event;
+extern struct object *create_event_sync( int manual, int signaled ); +extern void signal_sync( struct object *obj ); +extern void reset_sync( struct object *obj ); + extern struct event *create_event( struct object *root, const struct unicode_str *name, unsigned int attr, int manual_reset, int initial_state, const struct security_descriptor *sd );
v6: Move signal access checks to a type_descr signal_access field instead of checking types explicitly.