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.
-- v7: 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.
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 ffc016bfa56..f3afcc33d2f 100644 --- a/server/thread.c +++ b/server/thread.c @@ -922,8 +922,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; } @@ -932,7 +930,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 ) @@ -987,7 +984,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; @@ -1024,6 +1025,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 1f93cca437d..7dc5e868d88 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 ad7c09acc99..8d4a78d988a 100644 --- a/server/event.c +++ b/server/event.c @@ -75,6 +75,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 */ @@ -122,6 +123,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 8968df73647..141298ba4b7 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 ffe7206369e..88566253945 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 c54281c2101..f98fc4c0075 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -84,6 +84,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 */ @@ -145,6 +146,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 */ @@ -210,6 +212,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 */ @@ -240,6 +243,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 247b28cf6f5..7ece32b0231 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 af0efe72132..4737b6f711b 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -76,6 +76,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 6e4ae371a1b..b167c9b7083 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 */ @@ -261,6 +264,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 */ @@ -292,6 +296,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 */ @@ -342,6 +347,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 cd368ef724a..53570b90aed 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 1058f9bfb0a..513d1906020 100644 --- a/server/object.h +++ b/server/object.h @@ -84,6 +84,8 @@ struct object_ops int (*signal)(struct object *, unsigned int); /* 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 */ @@ -170,6 +172,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, unsigned int access ); 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 b161e3394ba..124f294d543 100644 --- a/server/process.c +++ b/server/process.c @@ -108,6 +108,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 */ @@ -159,6 +160,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 */ @@ -220,6 +222,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 b4b6069f927..bc0d7820d4a 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 c60c737feff..dc03a564736 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 53b42a886df..304a821bcec 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -73,6 +73,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 74b60162c01..b597b38ec1a 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 f3afcc33d2f..704e2aeca10 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 */ @@ -957,6 +960,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, unsigned int access ) +{ + struct object *sync = get_obj_sync( obj ); + int ret = sync->ops->signal( sync, access ); + release_object( sync ); + return ret; +} + /* finish waiting */ static unsigned int end_wait( struct thread *thread, unsigned int status ) { @@ -973,19 +1014,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; } @@ -1018,7 +1059,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( entry->obj, entry )) { wait->count = i; end_wait( current, get_error() ); @@ -1073,13 +1114,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; @@ -1195,7 +1236,7 @@ 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 )); + ret = object_sync_signal( obj, get_handle_access( current->process, handle ) ); 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 7e20c670a16..f51778e0e19 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 f7f9d5e517f..ffec6a907fe 100644 --- a/server/window.c +++ b/server/window.c @@ -110,6 +110,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 7dc5e868d88..ba306af7bb1 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 59b73c0245c..f282e66835a 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 f98fc4c0075..cbeb6363060 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -78,13 +78,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 */ @@ -237,13 +237,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 b167c9b7083..af0ab2ce7ae 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 */ @@ -290,13 +290,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 */ @@ -341,13 +341,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 | 195 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 143 insertions(+), 52 deletions(-)
diff --git a/server/event.c b/server/event.c index 8d4a78d988a..b5dff9b5b49 100644 --- a/server/event.c +++ b/server/event.c @@ -50,32 +50,133 @@ struct type_descr event_type = }, };
+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, unsigned int access); + +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, unsigned int access ) +{ + struct event_sync *event = (struct event_sync *)obj; + assert( obj->ops == &event_sync_ops ); + + if (!(access & EVENT_MODIFY_STATE)) + { + set_error( STATUS_ACCESS_DENIED ); + return 0; + } + 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, unsigned int access); +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 */ @@ -86,7 +187,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 */ };
@@ -149,9 +250,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; @@ -162,67 +268,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, unsigned int access ) +static void event_destroy( 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; -} - -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, @@ -315,14 +396,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 ); @@ -340,12 +428,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 | 19 +++++++++++------ server/fd.c | 56 ++++++++++++++++++++++++++++--------------------- server/object.h | 4 ++++ 3 files changed, 49 insertions(+), 30 deletions(-)
diff --git a/server/event.c b/server/event.c index b5dff9b5b49..3a228f2898f 100644 --- a/server/event.c +++ b/server/event.c @@ -55,6 +55,7 @@ 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 */ + unsigned int internal : 1; /* sync is an internal sync */ };
static void event_sync_dump( struct object *obj, int verbose ); @@ -87,18 +88,19 @@ 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, int internal ) { struct event_sync *event;
if (!(event = alloc_object( &event_sync_ops ))) return NULL; event->manual = manual; event->signaled = signaled; + event->internal = internal;
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 ); @@ -108,7 +110,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 ); @@ -120,8 +122,8 @@ 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 ); + fprintf( stderr, "Event manual=%d signaled=%d internal=%d\n", + event->manual, event->signaled, event->internal ); }
static int event_sync_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -144,6 +146,11 @@ static int event_sync_signal( struct object *obj, unsigned int access ) struct event_sync *event = (struct event_sync *)obj; assert( obj->ops == &event_sync_ops );
+ if (event->internal) + { + set_error( STATUS_OBJECT_TYPE_MISMATCH ); + return 0; + } if (!(access & EVENT_MODIFY_STATE)) { set_error( STATUS_ACCESS_DENIED ); @@ -253,7 +260,7 @@ struct event *create_event( struct object *root, const struct unicode_str *name, event->sync = NULL; list_init( &event->kernel_object );
- if (!(event->sync = create_event_sync( manual_reset, initial_state ))) + if (!(event->sync = create_event_sync( manual_reset, initial_state, 0 ))) { release_object( event ); return NULL; diff --git a/server/fd.c b/server/fd.c index 94fa3e2dae7..dccef9d35d4 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, 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, 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 513d1906020..33d918a77f7 100644 --- a/server/object.h +++ b/server/object.h @@ -218,6 +218,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, int internal ); +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 );
v5: Take references on the sync objects in get_sync, tweak creation to initialize sync member to NULL first.
Also I've created https://gitlab.winehq.org/wine/wine/-/merge_requests/7985 to give an overview of where I'd like this to go.
I've dropped the idea of splitting the interface, but I think using actual objects for sync with reference count is a good idea. In that branch it's used for instance to share the same sync primitive between console objects and its children, and avoid having to loop over them all to signal/reset them.