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.
-- v5: 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..eaf2119385a 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_fd_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 eaf2119385a..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_fd_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 | 45 +++++++++++++++++++++++++-------------------- server/object.h | 4 ++++ 3 files changed, 42 insertions(+), 26 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..0424c0ab510 100644 --- a/server/fd.c +++ b/server/fd.c @@ -128,6 +128,7 @@ struct closed_fd struct fd { struct object obj; /* object header */ + struct object *sync; /* sync object for wait/signal */ const struct fd_ops *fd_ops; /* file descriptor operations */ struct inode *inode; /* inode that this fd belongs to */ struct list inode_entry; /* entry in inode fd list */ @@ -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 */ @@ -1702,7 +1709,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,7 +1719,8 @@ 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) + if ((fd->poll_index = add_poll_user( fd )) == -1 || + !(fd->sync = create_event_sync( 1, 1, 1 ))) { release_object( fd ); return NULL; @@ -1742,7 +1749,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 +1759,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 +2168,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 +2186,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 );