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.
-- v2: server: Use an event as debug event sync. server: Use an event as file lock sync. server: Use an event as process startup info sync. server: Use an event as thread context sync. server: Use an event as thread apc sync. server: Use an event as fd sync.
From: Rémi Bernon rbernon@codeweavers.com
--- server/async.c | 19 +++++------ server/atom.c | 5 --- server/change.c | 11 ++---- server/clipboard.c | 5 --- server/completion.c | 26 +++++++++----- server/console.c | 83 +++++++++++++++++++++++++-------------------- server/debugger.c | 26 +++++++++----- server/device.c | 30 ++++++---------- server/directory.c | 10 ------ server/event.c | 26 +++++++++----- server/fd.c | 40 +++++++++++----------- server/file.c | 13 +++---- server/file.h | 4 ++- server/handle.c | 5 --- server/hook.c | 5 --- server/mailslot.c | 23 ++----------- server/mapping.c | 15 -------- server/mutex.c | 13 ++++--- server/named_pipe.c | 49 +++++--------------------- server/object.c | 20 +++++------ server/object.h | 27 ++++++++++----- server/process.c | 39 ++++++++++++++------- server/queue.c | 18 +++++----- server/registry.c | 5 --- server/request.c | 5 --- server/semaphore.c | 13 ++++--- server/serial.c | 7 +--- server/signal.c | 5 --- server/sock.c | 16 +-------- server/symlink.c | 5 --- server/thread.c | 53 ++++++++++++++++++----------- server/timer.c | 13 ++++--- server/token.c | 5 --- server/window.c | 5 --- server/winstation.c | 10 ------ 35 files changed, 288 insertions(+), 366 deletions(-)
diff --git a/server/async.c b/server/async.c index d2d929c9709..46ce1e3b6bc 100644 --- a/server/async.c +++ b/server/async.c @@ -70,16 +70,20 @@ static int async_signaled( struct object *obj, struct wait_queue_entry *entry ); static void async_satisfied( struct object * obj, struct wait_queue_entry *entry ); static void async_destroy( struct object *obj );
-static const struct object_ops async_ops = +static const struct sync_ops async_sync_ops = { - sizeof(struct async), /* size */ - &no_type, /* type */ - async_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ async_signaled, /* signaled */ async_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops async_ops = +{ + sizeof(struct async), /* size */ + &no_type, /* type */ + async_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -261,7 +265,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const struct a if (event) release_object( event ); return NULL; } - + async->obj.sync.ops = &async_sync_ops; async->thread = (struct thread *)grab_object( thread ); async->event = event; async->data = *data; @@ -695,11 +699,6 @@ static const struct object_ops iosb_ops = sizeof(struct iosb), /* size */ &no_type, /* type */ iosb_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/atom.c b/server/atom.c index ff0799f5880..04feea060fc 100644 --- a/server/atom.c +++ b/server/atom.c @@ -76,11 +76,6 @@ static const struct object_ops atom_table_ops = sizeof(struct atom_table), /* size */ &no_type, /* type */ atom_table_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/change.c b/server/change.c index f42ce066340..31fa33f2e96 100644 --- a/server/change.c +++ b/server/change.c @@ -109,11 +109,6 @@ 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 */ dir_get_fd, /* get_fd */ default_map_access, /* map_access */ dir_get_sd, /* get_sd */ @@ -1137,10 +1132,8 @@ struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode ) { struct dir *dir;
- dir = alloc_object( &dir_ops ); - if (!dir) - return NULL; - + if (!(dir = alloc_object( &dir_ops ))) return NULL; + dir->obj.sync.ops = &default_fd_sync_ops; list_init( &dir->change_records ); dir->filter = 0; dir->notified = 0; diff --git a/server/clipboard.c b/server/clipboard.c index 91f159bc7c9..814d3c8f901 100644 --- a/server/clipboard.c +++ b/server/clipboard.c @@ -73,11 +73,6 @@ static const struct object_ops clipboard_ops = sizeof(struct clipboard), /* size */ &no_type, /* type */ clipboard_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/completion.c b/server/completion.c index 99680ae0680..ad257a57f4d 100644 --- a/server/completion.c +++ b/server/completion.c @@ -84,16 +84,20 @@ static int completion_wait_signaled( struct object *obj, struct wait_queue_entry static void completion_wait_satisfied( struct object *obj, struct wait_queue_entry *entry ); static void completion_wait_destroy( struct object * );
-static const struct object_ops completion_wait_ops = +static const struct sync_ops completion_wait_sync_ops = { - sizeof(struct completion_wait), /* size */ - &no_type, /* type */ - completion_wait_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ completion_wait_signaled, /* signaled */ completion_wait_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops completion_wait_ops = +{ + sizeof(struct completion_wait), /* size */ + &no_type, /* type */ + completion_wait_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -158,16 +162,20 @@ static int completion_signaled( struct object *obj, struct wait_queue_entry *ent static int completion_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); static void completion_destroy( struct object * );
-static const struct object_ops completion_ops = +static const struct sync_ops completion_sync_ops = { - sizeof(struct completion), /* size */ - &completion_type, /* type */ - completion_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ completion_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops completion_ops = +{ + sizeof(struct completion), /* size */ + &completion_type, /* type */ + completion_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -250,6 +258,7 @@ static struct completion_wait *create_completion_wait( struct thread *thread ) struct completion_wait *wait;
if (!(wait = alloc_object( &completion_wait_ops ))) return NULL; + wait->obj.sync.ops = &completion_wait_sync_ops; wait->completion = NULL; wait->thread = thread; wait->msg = NULL; @@ -271,6 +280,7 @@ static struct completion *create_completion( struct object *root, const struct u { if (get_error() != STATUS_OBJECT_NAME_EXISTS) { + completion->obj.sync.ops = &completion_sync_ops; list_init( &completion->queue ); list_init( &completion->wait_queue ); completion->depth = 0; diff --git a/server/console.c b/server/console.c index de6f4e73e31..e0fb85e8cc5 100644 --- a/server/console.c +++ b/server/console.c @@ -76,16 +76,20 @@ static struct object *console_open_file( struct object *obj, unsigned int access unsigned int sharing, unsigned int options ); static int console_add_queue( struct object *obj, struct wait_queue_entry *entry );
-static const struct object_ops console_ops = +static const struct sync_ops console_sync_ops = { - sizeof(struct console), /* size */ - &file_type, /* type */ - console_dump, /* dump */ console_add_queue, /* add_queue */ remove_queue, /* remove_queue */ console_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops console_ops = +{ + sizeof(struct console), /* size */ + &file_type, /* type */ + console_dump, /* dump */ console_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -153,16 +157,20 @@ static struct object *console_server_lookup_name( struct object *obj, struct uni static struct object *console_server_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options );
-static const struct object_ops console_server_ops = +static const struct sync_ops console_server_sync_ops = { - sizeof(struct console_server), /* size */ - &file_type, /* type */ - console_server_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ console_server_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops console_server_ops = +{ + sizeof(struct console_server), /* size */ + &file_type, /* type */ + console_server_dump, /* dump */ console_server_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -222,16 +230,20 @@ static struct fd *screen_buffer_get_fd( struct object *obj ); static struct object *screen_buffer_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options );
-static const struct object_ops screen_buffer_ops = +static const struct sync_ops screen_buffer_sync_ops = { - sizeof(struct screen_buffer), /* size */ - &file_type, /* type */ - screen_buffer_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ screen_buffer_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops screen_buffer_ops = +{ + sizeof(struct screen_buffer), /* size */ + &file_type, /* type */ + screen_buffer_dump, /* dump */ screen_buffer_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -276,11 +288,6 @@ static const struct object_ops console_device_ops = sizeof(struct object), /* size */ &device_type, /* type */ console_device_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -310,16 +317,20 @@ static struct object *console_input_open_file( struct object *obj, unsigned int static struct fd *console_input_get_fd( struct object *obj ); static void console_input_destroy( struct object *obj );
-static const struct object_ops console_input_ops = +static const struct sync_ops console_input_sync_ops = { - sizeof(struct console_input), /* size */ - &device_type, /* type */ - console_input_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ console_input_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops console_input_ops = +{ + sizeof(struct console_input), /* size */ + &device_type, /* type */ + console_input_dump, /* dump */ console_input_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -369,16 +380,20 @@ static struct object *console_output_open_file( struct object *obj, unsigned int unsigned int sharing, unsigned int options ); static void console_output_destroy( struct object *obj );
-static const struct object_ops console_output_ops = +static const struct sync_ops console_output_sync_ops = { - sizeof(struct console_output), /* size */ - &device_type, /* type */ - console_output_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ console_output_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops console_output_ops = +{ + sizeof(struct console_output), /* size */ + &device_type, /* type */ + console_output_dump, /* dump */ console_output_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -432,11 +447,6 @@ static const struct object_ops console_connection_ops = sizeof(struct console_connection),/* size */ &device_type, /* type */ console_connection_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ console_connection_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -535,9 +545,8 @@ static struct object *create_console(void) { struct console *console;
- if (!(console = alloc_object( &console_ops ))) - return NULL; - + if (!(console = alloc_object( &console_ops ))) return NULL; + console->obj.sync.ops = &console_sync_ops; console->renderer = NULL; console->signaled = 0; console->active = NULL; @@ -641,9 +650,8 @@ static struct object *create_screen_buffer( struct console *console ) return NULL; }
- if (!(screen_buffer = alloc_object( &screen_buffer_ops ))) - return NULL; - + if (!(screen_buffer = alloc_object( &screen_buffer_ops ))) return NULL; + screen_buffer->obj.sync.ops = &screen_buffer_sync_ops; screen_buffer->id = ++console->last_id; screen_buffer->input = console; init_async_queue( &screen_buffer->ioctl_q ); @@ -957,6 +965,7 @@ static struct object *create_console_server( void ) struct console_server *server;
if (!(server = alloc_object( &console_server_ops ))) return NULL; + server->obj.sync.ops = &console_server_sync_ops; server->console = NULL; server->busy = 0; server->once_input = 0; @@ -1337,6 +1346,7 @@ static struct object *console_device_lookup_name( struct object *obj, struct uni
name->len = 0; if (!(console_input = alloc_object( &console_input_ops ))) return NULL; + console_input->obj.sync.ops = &console_input_sync_ops; console_input->fd = alloc_pseudo_fd( &console_input_fd_ops, &console_input->obj, FILE_SYNCHRONOUS_IO_NONALERT ); if (!console_input->fd) @@ -1361,6 +1371,7 @@ static struct object *console_device_lookup_name( struct object *obj, struct uni
name->len = 0; if (!(console_output = alloc_object( &console_output_ops ))) return NULL; + console_output->obj.sync.ops = &console_output_sync_ops; console_output->fd = alloc_pseudo_fd( &console_output_fd_ops, &console_output->obj, FILE_SYNCHRONOUS_IO_NONALERT ); if (!console_output->fd) diff --git a/server/debugger.c b/server/debugger.c index 39a740e07e5..09c17712d17 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -78,16 +78,20 @@ static void debug_event_dump( struct object *obj, int verbose ); static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry ); static void debug_event_destroy( struct object *obj );
-static const struct object_ops debug_event_ops = +static const struct sync_ops debug_event_sync_ops = { - sizeof(struct debug_event), /* size */ - &no_type, /* type */ - debug_event_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ debug_event_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops debug_event_ops = +{ + sizeof(struct debug_event), /* size */ + &no_type, /* type */ + debug_event_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -106,16 +110,20 @@ static void debug_obj_dump( struct object *obj, int verbose ); static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entry ); static void debug_obj_destroy( struct object *obj );
-static const struct object_ops debug_obj_ops = +static const struct sync_ops debug_obj_sync_ops = { - sizeof(struct debug_obj), /* size */ - &debug_obj_type, /* type */ - debug_obj_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ debug_obj_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops debug_obj_ops = +{ + sizeof(struct debug_obj), /* size */ + &debug_obj_type, /* type */ + debug_obj_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -359,6 +367,7 @@ static struct debug_obj *create_debug_obj( struct object *root, const struct uni { if (get_error() != STATUS_OBJECT_NAME_EXISTS) { + debug_obj->obj.sync.ops = &debug_obj_sync_ops; debug_obj->flags = flags; list_init( &debug_obj->event_queue ); } @@ -427,6 +436,7 @@ static struct debug_event *alloc_debug_event( struct thread *thread, int code, c
/* build the event */ if (!(event = alloc_object( &debug_event_ops ))) return NULL; + event->obj.sync.ops = &debug_event_sync_ops; event->state = EVENT_QUEUED; event->sender = (struct thread *)grab_object( thread ); event->file = NULL; diff --git a/server/device.c b/server/device.c index 1f93cca437d..13a6728939b 100644 --- a/server/device.c +++ b/server/device.c @@ -63,11 +63,6 @@ static const struct object_ops irp_call_ops = sizeof(struct irp_call), /* size */ &no_type, /* type */ irp_call_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -98,16 +93,20 @@ static void device_manager_dump( struct object *obj, int verbose ); static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry ); static void device_manager_destroy( struct object *obj );
-static const struct object_ops device_manager_ops = +static const struct sync_ops device_manager_sync_ops = { - sizeof(struct device_manager), /* size */ - &no_type, /* type */ - device_manager_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ device_manager_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops device_manager_ops = +{ + sizeof(struct device_manager), /* size */ + &no_type, /* type */ + device_manager_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -160,11 +159,6 @@ static const struct object_ops device_ops = sizeof(struct device), /* size */ &device_type, /* type */ device_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -212,11 +206,6 @@ 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 */ device_file_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -429,7 +418,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access, struct unicode_str nt_name;
if (!(file = alloc_object( &device_file_ops ))) return NULL; - + file->obj.sync.ops = &default_fd_sync_ops; file->device = (struct device *)grab_object( device ); file->closed = 0; list_init( &file->kernel_object ); @@ -825,6 +814,7 @@ static struct device_manager *create_device_manager(void)
if ((manager = alloc_object( &device_manager_ops ))) { + manager->obj.sync.ops = &device_manager_sync_ops; manager->current_call = NULL; list_init( &manager->devices ); list_init( &manager->requests ); diff --git a/server/directory.c b/server/directory.c index fd689c561bc..6abd7e5c238 100644 --- a/server/directory.c +++ b/server/directory.c @@ -66,11 +66,6 @@ static const struct object_ops object_type_ops = sizeof(struct object_type), /* size */ &objtype_type, /* type */ object_type_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -116,11 +111,6 @@ static const struct object_ops directory_ops = sizeof(struct directory), /* size */ &directory_type, /* type */ directory_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/event.c b/server/event.c index ad7c09acc99..f9aa2d6244d 100644 --- a/server/event.c +++ b/server/event.c @@ -64,16 +64,20 @@ static void event_satisfied( struct object *obj, struct wait_queue_entry *entry static int event_signal( struct object *obj, unsigned int access); static struct list *event_get_kernel_obj_list( struct object *obj );
-static const struct object_ops event_ops = +static const struct sync_ops event_sync_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 */ +}; + +static const struct object_ops event_ops = +{ + sizeof(struct event), /* size */ + &event_type, /* type */ + event_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -111,16 +115,20 @@ struct keyed_event static void keyed_event_dump( struct object *obj, int verbose ); static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *entry );
-static const struct object_ops keyed_event_ops = +static const struct sync_ops keyed_event_sync_ops = { - sizeof(struct keyed_event), /* size */ - &keyed_event_type, /* type */ - keyed_event_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ keyed_event_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops keyed_event_ops = +{ + sizeof(struct keyed_event), /* size */ + &keyed_event_type, /* type */ + keyed_event_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -147,6 +155,7 @@ 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->obj.sync.ops = &event_sync_ops; list_init( &event->kernel_object ); event->manual_reset = manual_reset; event->signaled = initial_state; @@ -233,6 +242,7 @@ struct keyed_event *create_keyed_event( struct object *root, const struct unicod if (get_error() != STATUS_OBJECT_NAME_EXISTS) { /* initialize it if it didn't already exist */ + event->obj.sync.ops = &keyed_event_sync_ops; } } return event; diff --git a/server/fd.c b/server/fd.c index bb0e90d99d0..b9366ee69e0 100644 --- a/server/fd.c +++ b/server/fd.c @@ -157,18 +157,23 @@ struct fd };
static void fd_dump( struct object *obj, int verbose ); +static int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry ); static void fd_destroy( struct object *obj );
+const struct sync_ops default_fd_sync_ops = +{ + add_queue, /* add_queue */ + remove_queue, /* remove_queue */ + default_fd_signaled, /* signaled */ + no_satisfied, /* satisfied */ + no_signal, /* signal */ +}; + 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 */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -205,11 +210,6 @@ static const struct object_ops device_ops = sizeof(struct device), /* size */ &no_type, /* type */ device_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -245,11 +245,6 @@ static const struct object_ops inode_ops = sizeof(struct inode), /* size */ &no_type, /* type */ inode_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -282,16 +277,20 @@ struct file_lock static void file_lock_dump( struct object *obj, int verbose ); static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry );
-static const struct object_ops file_lock_ops = +static const struct sync_ops file_lock_sync_ops = { - sizeof(struct file_lock), /* size */ - &no_type, /* type */ - file_lock_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ file_lock_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops file_lock_ops = +{ + sizeof(struct file_lock), /* size */ + &no_type, /* type */ + file_lock_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -1422,6 +1421,7 @@ static struct file_lock *add_lock( struct fd *fd, int shared, file_pos_t start, struct file_lock *lock;
if (!(lock = alloc_object( &file_lock_ops ))) return NULL; + lock->obj.sync.ops = &file_lock_sync_ops; lock->shared = shared; lock->start = start; lock->end = end; @@ -2170,7 +2170,7 @@ int check_fd_events( struct fd *fd, int events ) }
/* default signaled() routine for objects that poll() on an fd */ -int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct fd *fd = get_obj_fd( obj ); int ret = fd->signaled; diff --git a/server/file.c b/server/file.c index 8f6566a0077..666b1a6f55e 100644 --- a/server/file.c +++ b/server/file.c @@ -91,11 +91,6 @@ 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 */ file_get_fd, /* get_fd */ default_map_access, /* map_access */ file_get_sd, /* get_sd */ @@ -145,7 +140,7 @@ struct file *create_file_for_fd( int fd, unsigned int access, unsigned int shari close( fd ); return NULL; } - + file->obj.sync.ops = &default_fd_sync_ops; file->mode = st.st_mode; file->access = default_map_access( &file->obj, access ); list_init( &file->kernel_object ); @@ -173,6 +168,7 @@ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigne
if ((file = alloc_object( &file_ops ))) { + file->obj.sync.ops = &default_fd_sync_ops; file->mode = st.st_mode; file->access = default_map_access( &file->obj, access ); list_init( &file->kernel_object ); @@ -188,9 +184,10 @@ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigne
static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_t mode ) { - struct file *file = alloc_object( &file_ops ); + struct file *file;
- if (!file) return NULL; + if (!(file = alloc_object( &file_ops ))) return NULL; + file->obj.sync.ops = &default_fd_sync_ops; file->access = access; file->mode = mode; file->uid = ~(uid_t)0; diff --git a/server/file.h b/server/file.h index 59b73c0245c..66a67ec4a16 100644 --- a/server/file.h +++ b/server/file.h @@ -24,6 +24,7 @@ #include <sys/types.h>
#include "object.h" +#include "thread.h"
struct fd; struct mapping; @@ -108,7 +109,6 @@ 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 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 ); @@ -132,6 +132,8 @@ extern void remove_process_locks( struct process *process );
static inline struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get_fd( obj ); }
+extern const struct sync_ops default_fd_sync_ops; + /* timeout functions */
struct timeout_user; diff --git a/server/handle.c b/server/handle.c index 8968df73647..39dad955ed2 100644 --- a/server/handle.c +++ b/server/handle.c @@ -123,11 +123,6 @@ static const struct object_ops handle_table_ops = sizeof(struct handle_table), /* size */ &no_type, /* type */ handle_table_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/hook.c b/server/hook.c index ffe7206369e..45e185f9896 100644 --- a/server/hook.c +++ b/server/hook.c @@ -78,11 +78,6 @@ static const struct object_ops hook_table_ops = sizeof(struct hook_table), /* size */ &no_type, /* type */ hook_table_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/mailslot.c b/server/mailslot.c index c54281c2101..3d338b06e71 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -78,11 +78,6 @@ 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 */ mailslot_get_fd, /* get_fd */ mailslot_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -139,11 +134,6 @@ static const struct object_ops mail_writer_ops = sizeof(struct mail_writer), /* size */ &file_type, /* type */ mail_writer_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ mail_writer_get_fd, /* get_fd */ mail_writer_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -204,11 +194,6 @@ static const struct object_ops mailslot_device_ops = sizeof(struct mailslot_device), /* size */ &device_type, /* type */ mailslot_device_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -234,11 +219,6 @@ 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 */ mailslot_device_file_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -483,6 +463,7 @@ static struct object *mailslot_device_open_file( struct object *obj, unsigned in struct mailslot_device_file *file;
if (!(file = alloc_object( &mailslot_device_file_ops ))) return NULL; + file->obj.sync.ops = &default_fd_sync_ops; file->device = (struct mailslot_device *)grab_object( obj ); if (!(file->fd = alloc_pseudo_fd( &mailslot_device_fd_ops, obj, options ))) { @@ -558,7 +539,7 @@ static struct mailslot *create_mailslot( struct object *root, struct mailslot *mailslot;
if (!(mailslot = create_named_object( root, &mailslot_ops, name, attr & ~OBJ_OPENIF, sd ))) return NULL; - + mailslot->obj.sync.ops = &default_fd_sync_ops; mailslot->fd = NULL; mailslot->max_msgsize = max_msgsize; mailslot->read_timeout = read_timeout; diff --git a/server/mapping.c b/server/mapping.c index 247b28cf6f5..a755577a77f 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -64,11 +64,6 @@ static const struct object_ops ranges_ops = sizeof(struct ranges), /* size */ &no_type, /* type */ ranges_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -100,11 +95,6 @@ static const struct object_ops shared_map_ops = sizeof(struct shared_map), /* size */ &no_type, /* type */ shared_map_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -173,11 +163,6 @@ static const struct object_ops mapping_ops = sizeof(struct mapping), /* size */ &mapping_type, /* type */ mapping_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ mapping_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/mutex.c b/server/mutex.c index af0efe72132..5b7184e6913 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -65,16 +65,20 @@ static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry static void mutex_destroy( struct object *obj ); static int mutex_signal( struct object *obj, unsigned int access );
-static const struct object_ops mutex_ops = +static const struct sync_ops mutex_sync_ops = { - sizeof(struct mutex), /* size */ - &mutex_type, /* type */ - mutex_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ mutex_signaled, /* signaled */ mutex_satisfied, /* satisfied */ mutex_signal, /* signal */ +}; + +static const struct object_ops mutex_ops = +{ + sizeof(struct mutex), /* size */ + &mutex_type, /* type */ + mutex_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -123,6 +127,7 @@ static struct mutex *create_mutex( struct object *root, const struct unicode_str if (get_error() != STATUS_OBJECT_NAME_EXISTS) { /* initialize it if it didn't already exist */ + mutex->obj.sync.ops = &mutex_sync_ops; mutex->count = 0; mutex->owner = NULL; mutex->abandoned = 0; diff --git a/server/named_pipe.c b/server/named_pipe.c index 6e4ae371a1b..a281e908fe6 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -116,11 +116,6 @@ static const struct object_ops named_pipe_ops = sizeof(struct named_pipe), /* size */ &no_type, /* type */ named_pipe_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ named_pipe_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -164,11 +159,6 @@ 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 */ pipe_end_get_fd, /* get_fd */ default_map_access, /* map_access */ pipe_end_get_sd, /* get_sd */ @@ -208,11 +198,6 @@ 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 */ pipe_end_get_fd, /* get_fd */ default_map_access, /* map_access */ pipe_end_get_sd, /* get_sd */ @@ -255,11 +240,6 @@ static const struct object_ops named_pipe_device_ops = sizeof(struct named_pipe_device), /* size */ &device_type, /* type */ named_pipe_device_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -286,11 +266,6 @@ 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 */ named_pipe_device_file_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -336,11 +311,6 @@ 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 */ named_pipe_dir_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -554,10 +524,10 @@ static struct object *named_pipe_device_lookup_name( struct object *obj, struct if (!name->len && name->str) { /* open the root directory */ - struct named_pipe_device_file *dir = alloc_object( &named_pipe_dir_ops ); - - if (!dir) return NULL; + struct named_pipe_device_file *dir;
+ if (!(dir = alloc_object( &named_pipe_dir_ops ))) return NULL; + dir->obj.sync.ops = &default_fd_sync_ops; dir->fd = NULL; /* defer alloc_pseudo_fd() until after we have options */ dir->device = (struct named_pipe_device *)grab_object( obj );
@@ -576,6 +546,7 @@ static struct object *named_pipe_device_open_file( struct object *obj, unsigned struct named_pipe_device_file *file;
if (!(file = alloc_object( &named_pipe_device_file_ops ))) return NULL; + file->obj.sync.ops = &default_fd_sync_ops; file->device = (struct named_pipe_device *)grab_object( obj ); if (!(file->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, obj, options ))) { @@ -1406,10 +1377,8 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned { struct pipe_server *server;
- server = alloc_object( &pipe_server_ops ); - if (!server) - return NULL; - + if (!(server = alloc_object( &pipe_server_ops ))) return NULL; + server->pipe_end.obj.sync.ops = &default_fd_sync_ops; server->options = options; init_pipe_end( &server->pipe_end, pipe, pipe_flags, pipe->insize ); server->pipe_end.state = FILE_PIPE_LISTENING_STATE; @@ -1432,10 +1401,8 @@ static struct pipe_end *create_pipe_client( struct named_pipe *pipe, data_size_t { struct pipe_end *client;
- client = alloc_object( &pipe_client_ops ); - if (!client) - return NULL; - + if (!(client = alloc_object( &pipe_client_ops ))) return NULL; + client->obj.sync.ops = &default_fd_sync_ops; init_pipe_end( client, pipe, 0, buffer_size ); client->state = FILE_PIPE_CONNECTED_STATE; client->client_pid = get_process_id( current->process ); diff --git a/server/object.c b/server/object.c index cd368ef724a..70f83870bf7 100644 --- a/server/object.c +++ b/server/object.c @@ -105,11 +105,6 @@ static const struct object_ops apc_reserve_ops = sizeof(struct reserve), /* size */ &apc_reserve_type, /* type */ dump_reserve, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -129,11 +124,6 @@ static const struct object_ops completion_reserve_ops = sizeof(struct reserve), /* size */ &completion_reserve_type, /* type */ dump_reserve, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -295,6 +285,15 @@ WCHAR *default_get_full_name( struct object *obj, data_size_t *ret_len ) return (WCHAR *)ret; }
+static const struct sync_ops no_sync_ops = +{ + no_add_queue, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + no_signal, /* signal */ +}; + /* allocate and initialize an object */ void *alloc_object( const struct object_ops *ops ) { @@ -305,6 +304,7 @@ void *alloc_object( const struct object_ops *ops ) obj->handle_count = 0; obj->is_permanent = 0; obj->ops = ops; + obj->sync.ops = &no_sync_ops; obj->name = NULL; obj->sd = NULL; list_init( &obj->wait_queue ); diff --git a/server/object.h b/server/object.h index 1058f9bfb0a..199ce98ed65 100644 --- a/server/object.h +++ b/server/object.h @@ -63,15 +63,9 @@ struct type_descr unsigned int handle_max; /* max count of handles of this type */ };
-/* operations valid on all objects */ -struct object_ops +/* operations valid on waitable objects */ +struct sync_ops { - /* size of this object type */ - size_t size; - /* type descriptor */ - struct type_descr *type; - /* dump the object (for debugging) */ - void (*dump)(struct object *,int); /* add a thread to the object wait queue */ int (*add_queue)(struct object *,struct wait_queue_entry *); /* remove a thread from the object wait queue */ @@ -82,6 +76,22 @@ struct object_ops void (*satisfied)(struct object *,struct wait_queue_entry *); /* signal an object */ int (*signal)(struct object *, unsigned int); +}; + +struct sync +{ + const struct sync_ops *ops; +}; + +/* operations valid on all objects */ +struct object_ops +{ + /* size of this object type */ + size_t size; + /* type descriptor */ + struct type_descr *type; + /* dump the object (for debugging) */ + void (*dump)(struct object *,int); /* return an fd object that can be used to read/write from the object */ struct fd *(*get_fd)(struct object *); /* map access rights to the specific rights for this object */ @@ -114,6 +124,7 @@ struct object unsigned int refcount; /* reference count */ unsigned int handle_count;/* handle count */ const struct object_ops *ops; + struct sync sync; struct list wait_queue; struct object_name *name; struct security_descriptor *sd; diff --git a/server/process.c b/server/process.c index b161e3394ba..19ece8c56c4 100644 --- a/server/process.c +++ b/server/process.c @@ -97,16 +97,20 @@ static struct list *process_get_kernel_obj_list( struct object *obj ); static void process_destroy( struct object *obj ); static void terminate_process( struct process *process, struct thread *skip, int exit_code );
-static const struct object_ops process_ops = +static const struct sync_ops process_sync_ops = { - sizeof(struct process), /* size */ - &process_type, /* type */ - process_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ process_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops process_ops = +{ + sizeof(struct process), /* size */ + &process_type, /* type */ + process_dump, /* dump */ no_get_fd, /* get_fd */ process_map_access, /* map_access */ process_get_sd, /* get_sd */ @@ -148,16 +152,20 @@ static void startup_info_dump( struct object *obj, int verbose ); static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry ); static void startup_info_destroy( struct object *obj );
-static const struct object_ops startup_info_ops = +static const struct sync_ops startup_info_sync_ops = { - sizeof(struct startup_info), /* size */ - &no_type, /* type */ - startup_info_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ startup_info_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops startup_info_ops = +{ + sizeof(struct startup_info), /* size */ + &no_type, /* type */ + startup_info_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -209,16 +217,20 @@ struct job struct list child_job_list; /* list of child jobs */ };
-static const struct object_ops job_ops = +static const struct sync_ops job_sync_ops = { - sizeof(struct job), /* size */ - &job_type, /* type */ - job_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ job_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops job_ops = +{ + sizeof(struct job), /* size */ + &job_type, /* type */ + job_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -243,6 +255,7 @@ static struct job *create_job_object( struct object *root, const struct unicode_ if (get_error() != STATUS_OBJECT_NAME_EXISTS) { /* initialize it if it didn't already exist */ + job->obj.sync.ops = &job_sync_ops; list_init( &job->process_list ); list_init( &job->child_job_list ); job->num_processes = 0; @@ -650,6 +663,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla close( fd ); goto error; } + process->obj.sync.ops = &process_sync_ops; process->parent_id = 0; process->debug_obj = NULL; process->debug_event = NULL; @@ -1199,6 +1213,7 @@ DECL_HANDLER(new_process) release_object( parent ); return; } + info->obj.sync.ops = &startup_info_sync_ops; info->process = NULL; info->data = NULL;
diff --git a/server/queue.c b/server/queue.c index b4b6069f927..7146ee51a2c 100644 --- a/server/queue.c +++ b/server/queue.c @@ -157,16 +157,20 @@ static void thread_input_dump( struct object *obj, int verbose ); static void thread_input_destroy( struct object *obj ); static void timer_callback( void *private );
-static const struct object_ops msg_queue_ops = +static const struct sync_ops msg_queue_sync_ops = { - sizeof(struct msg_queue), /* size */ - &no_type, /* type */ - msg_queue_dump, /* dump */ msg_queue_add_queue, /* add_queue */ msg_queue_remove_queue, /* remove_queue */ msg_queue_signaled, /* signaled */ msg_queue_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops msg_queue_ops = +{ + sizeof(struct msg_queue), /* size */ + &no_type, /* type */ + msg_queue_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -199,11 +203,6 @@ static const struct object_ops thread_input_ops = sizeof(struct thread_input), /* size */ &no_type, /* type */ thread_input_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -301,6 +300,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
if ((queue = alloc_object( &msg_queue_ops ))) { + queue->obj.sync.ops = &msg_queue_sync_ops; queue->fd = NULL; queue->paint_count = 0; queue->hotkey_count = 0; diff --git a/server/registry.c b/server/registry.c index c60c737feff..bd80d3e7399 100644 --- a/server/registry.c +++ b/server/registry.c @@ -177,11 +177,6 @@ static const struct object_ops key_ops = sizeof(struct key), /* size */ &key_type, /* type */ key_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ key_map_access, /* map_access */ key_get_sd, /* get_sd */ diff --git a/server/request.c b/server/request.c index 2254315b79e..474750523bf 100644 --- a/server/request.c +++ b/server/request.c @@ -86,11 +86,6 @@ static const struct object_ops master_socket_ops = sizeof(struct master_socket), /* size */ &no_type, /* type */ master_socket_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/semaphore.c b/server/semaphore.c index 53b42a886df..7c7de0f77f7 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -62,16 +62,20 @@ static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entr static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ); static int semaphore_signal( struct object *obj, unsigned int access );
-static const struct object_ops semaphore_ops = +static const struct sync_ops semaphore_sync_ops = { - sizeof(struct semaphore), /* size */ - &semaphore_type, /* type */ - semaphore_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ semaphore_signaled, /* signaled */ semaphore_satisfied, /* satisfied */ semaphore_signal, /* signal */ +}; + +static const struct object_ops semaphore_ops = +{ + sizeof(struct semaphore), /* size */ + &semaphore_type, /* type */ + semaphore_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -103,6 +107,7 @@ static struct semaphore *create_semaphore( struct object *root, const struct uni if (get_error() != STATUS_OBJECT_NAME_EXISTS) { /* initialize it if it didn't already exist */ + sem->obj.sync.ops = &semaphore_sync_ops; sem->count = initial; sem->max = max; } diff --git a/server/serial.c b/server/serial.c index 209f2e9174e..aedc962174a 100644 --- a/server/serial.c +++ b/server/serial.c @@ -88,11 +88,6 @@ 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 */ serial_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -137,7 +132,7 @@ struct object *create_serial( struct fd *fd ) struct serial *serial;
if (!(serial = alloc_object( &serial_ops ))) return NULL; - + serial->obj.sync.ops = &default_fd_sync_ops; serial->read_timer = NULL; serial->eventmask = 0; serial->pending_write = 0; diff --git a/server/signal.c b/server/signal.c index 19b76d44c16..8016c507367 100644 --- a/server/signal.c +++ b/server/signal.c @@ -59,11 +59,6 @@ static const struct object_ops handler_ops = sizeof(struct handler), /* size */ &no_type, /* type */ handler_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/sock.c b/server/sock.c index e064f867ff4..4dd973ae7d8 100644 --- a/server/sock.c +++ b/server/sock.c @@ -483,11 +483,6 @@ 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 */ sock_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -1782,6 +1777,7 @@ static struct sock *create_socket(void) struct sock *sock;
if (!(sock = alloc_object( &sock_ops ))) return NULL; + sock->obj.sync.ops = &default_fd_sync_ops; sock->fd = NULL; sock->state = SOCK_UNCONNECTED; sock->mask = 0; @@ -3692,11 +3688,6 @@ static const struct object_ops ifchange_ops = sizeof(struct ifchange), /* size */ &no_type, /* type */ ifchange_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ ifchange_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -3913,11 +3904,6 @@ static const struct object_ops socket_device_ops = sizeof(struct object), /* size */ &device_type, /* type */ socket_device_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/symlink.c b/server/symlink.c index 74b60162c01..125130fc90c 100644 --- a/server/symlink.c +++ b/server/symlink.c @@ -68,11 +68,6 @@ static const struct object_ops symlink_ops = sizeof(struct symlink), /* size */ &symlink_type, /* type */ symlink_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/thread.c b/server/thread.c index ffc016bfa56..ea4432ec6a6 100644 --- a/server/thread.c +++ b/server/thread.c @@ -98,16 +98,20 @@ static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *ent static void thread_apc_destroy( struct object *obj ); static void clear_apc_queue( struct list *queue );
-static const struct object_ops thread_apc_ops = +static const struct sync_ops thread_apc_sync_ops = { - sizeof(struct thread_apc), /* size */ - &no_type, /* type */ - dump_thread_apc, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ thread_apc_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops thread_apc_ops = +{ + sizeof(struct thread_apc), /* size */ + &no_type, /* type */ + dump_thread_apc, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -140,16 +144,20 @@ static const unsigned int system_flags = SERVER_CTX_DEBUG_REGISTERS; static void dump_context( struct object *obj, int verbose ); static int context_signaled( struct object *obj, struct wait_queue_entry *entry );
-static const struct object_ops context_ops = +static const struct sync_ops context_sync_ops = { - sizeof(struct context), /* size */ - &no_type, /* type */ - dump_context, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ context_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops context_ops = +{ + sizeof(struct context), /* size */ + &no_type, /* type */ + dump_context, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -189,16 +197,20 @@ static void thread_poll_event( struct fd *fd, int event ); static struct list *thread_get_kernel_obj_list( struct object *obj ); static void destroy_thread( struct object *obj );
-static const struct object_ops thread_ops = +static const struct sync_ops thread_sync_ops = { - sizeof(struct thread), /* size */ - &thread_type, /* type */ - dump_thread, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ thread_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops thread_ops = +{ + sizeof(struct thread), /* size */ + &thread_type, /* type */ + dump_thread, /* dump */ no_get_fd, /* get_fd */ thread_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -389,6 +401,7 @@ static inline void init_thread_structure( struct thread *thread ) { int i;
+ thread->obj.sync.ops = &thread_sync_ops; thread->unix_pid = -1; /* not known yet */ thread->unix_tid = -1; /* not known yet */ thread->context = NULL; @@ -458,6 +471,7 @@ static struct context *create_thread_context( struct thread *thread ) { struct context *context; if (!(context = alloc_object( &context_ops ))) return NULL; + context->obj.sync.ops = &context_sync_ops; context->status = STATUS_PENDING; memset( &context->regs, 0, sizeof(context->regs) ); context->regs[CTX_NATIVE].machine = native_machine; @@ -683,6 +697,7 @@ static struct thread_apc *create_apc( struct object *owner, const union apc_call
if ((apc = alloc_object( &thread_apc_ops ))) { + apc->obj.sync.ops = &thread_apc_sync_ops; if (call_data) apc->call = *call_data; else apc->call.type = APC_NONE; apc->caller = NULL; @@ -976,18 +991,18 @@ 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 ); + entry->obj->sync.ops->satisfied( entry->obj, entry ); } else { entry = wait->queues + status; - entry->obj->ops->satisfied( entry->obj, entry ); + entry->obj->sync.ops->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 ); + entry->obj->sync.ops->remove_queue( entry->obj, entry ); if (wait->user) remove_timeout_user( wait->user ); free( wait ); return status; @@ -1017,7 +1032,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 (!obj->sync.ops->add_queue( obj, entry )) { wait->count = i; end_wait( current, get_error() ); @@ -1071,13 +1086,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 |= !entry->obj->sync.ops->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 (entry->obj->sync.ops->signaled( entry->obj, entry )) return i; }
if ((wait->flags & SELECT_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC; @@ -1193,7 +1208,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 = obj->sync.ops->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..c82845cf80f 100644 --- a/server/timer.c +++ b/server/timer.c @@ -68,16 +68,20 @@ static int timer_signaled( struct object *obj, struct wait_queue_entry *entry ); static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry ); static void timer_destroy( struct object *obj );
-static const struct object_ops timer_ops = +static const struct sync_ops timer_sync_ops = { - sizeof(struct timer), /* size */ - &timer_type, /* type */ - timer_dump, /* dump */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ timer_signaled, /* signaled */ timer_satisfied, /* satisfied */ no_signal, /* signal */ +}; + +static const struct object_ops timer_ops = +{ + sizeof(struct timer), /* size */ + &timer_type, /* type */ + timer_dump, /* dump */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -104,6 +108,7 @@ static struct timer *create_timer( struct object *root, const struct unicode_str if (get_error() != STATUS_OBJECT_NAME_EXISTS) { /* initialize it if it didn't already exist */ + timer->obj.sync.ops = &timer_sync_ops; timer->manual = manual; timer->signaled = 0; timer->when = 0; diff --git a/server/token.c b/server/token.c index 7e20c670a16..e7a975ae793 100644 --- a/server/token.c +++ b/server/token.c @@ -142,11 +142,6 @@ static const struct object_ops token_ops = sizeof(struct token), /* size */ &token_type, /* type */ token_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/window.c b/server/window.c index f7f9d5e517f..da215ab5b78 100644 --- a/server/window.c +++ b/server/window.c @@ -104,11 +104,6 @@ static const struct object_ops window_ops = sizeof(struct window), /* size */ &no_type, /* type */ window_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ diff --git a/server/winstation.c b/server/winstation.c index b3746090ccf..5b33abb257f 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -73,11 +73,6 @@ static const struct object_ops winstation_ops = sizeof(struct winstation), /* size */ &winstation_type, /* type */ winstation_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ @@ -113,11 +108,6 @@ static const struct object_ops desktop_ops = sizeof(struct desktop), /* size */ &desktop_type, /* type */ desktop_dump, /* dump */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ no_get_fd, /* get_fd */ default_map_access, /* map_access */ default_get_sd, /* get_sd */
From: Rémi Bernon rbernon@codeweavers.com
--- server/async.c | 10 ++++++ server/atom.c | 1 + server/change.c | 2 +- server/clipboard.c | 1 + server/completion.c | 19 +++++++++- server/console.c | 47 ++++++++++++++++++++++++ server/debugger.c | 18 ++++++++++ server/device.c | 13 ++++++- server/directory.c | 2 ++ server/event.c | 18 ++++++++++ server/fd.c | 54 ++++++++++++++++++++-------- server/file.c | 4 +-- server/file.h | 3 +- server/handle.c | 1 + server/hook.c | 1 + server/mailslot.c | 6 ++-- server/mapping.c | 3 ++ server/mutex.c | 9 +++++ server/named_pipe.c | 10 +++--- server/object.c | 12 +++++++ server/object.h | 3 ++ server/process.c | 27 ++++++++++++++ server/queue.c | 10 ++++++ server/registry.c | 1 + server/request.c | 1 + server/semaphore.c | 9 +++++ server/serial.c | 2 +- server/signal.c | 1 + server/sock.c | 4 ++- server/symlink.c | 1 + server/thread.c | 87 +++++++++++++++++++++++++++++++++++++++++---- server/timer.c | 9 +++++ server/token.c | 1 + server/window.c | 1 + server/winstation.c | 2 ++ 35 files changed, 356 insertions(+), 37 deletions(-)
diff --git a/server/async.c b/server/async.c index 46ce1e3b6bc..50c4bcf58c2 100644 --- a/server/async.c +++ b/server/async.c @@ -66,6 +66,7 @@ struct async };
static void async_dump( struct object *obj, int verbose ); +static struct sync *async_get_sync( struct object *obj ); static int async_signaled( struct object *obj, struct wait_queue_entry *entry ); static void async_satisfied( struct object * obj, struct wait_queue_entry *entry ); static void async_destroy( struct object *obj ); @@ -85,6 +86,7 @@ static const struct object_ops async_ops = &no_type, /* type */ async_dump, /* dump */ no_get_fd, /* get_fd */ + async_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -110,6 +112,13 @@ static void async_dump( struct object *obj, int verbose ) fprintf( stderr, "Async thread=%p\n", async->thread ); }
+static struct sync *async_get_sync( struct object *obj ) +{ + struct async *async = (struct async *)obj; + assert( obj->ops == &async_ops ); + return &async->obj.sync; +} + static int async_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct async *async = (struct async *)obj; @@ -700,6 +709,7 @@ static const struct object_ops iosb_ops = &no_type, /* type */ iosb_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 04feea060fc..ef2ca3b360a 100644 --- a/server/atom.c +++ b/server/atom.c @@ -77,6 +77,7 @@ static const struct object_ops atom_table_ops = &no_type, /* type */ atom_table_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 31fa33f2e96..bdc7c7fe7d3 100644 --- a/server/change.c +++ b/server/change.c @@ -110,6 +110,7 @@ static const struct object_ops dir_ops = &file_type, /* type */ dir_dump, /* dump */ dir_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ dir_get_sd, /* get_sd */ dir_set_sd, /* set_sd */ @@ -1133,7 +1134,6 @@ struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode ) struct dir *dir;
if (!(dir = alloc_object( &dir_ops ))) return NULL; - dir->obj.sync.ops = &default_fd_sync_ops; list_init( &dir->change_records ); dir->filter = 0; dir->notified = 0; diff --git a/server/clipboard.c b/server/clipboard.c index 814d3c8f901..bc7855cd081 100644 --- a/server/clipboard.c +++ b/server/clipboard.c @@ -74,6 +74,7 @@ static const struct object_ops clipboard_ops = &no_type, /* type */ clipboard_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 ad257a57f4d..052112866a4 100644 --- a/server/completion.c +++ b/server/completion.c @@ -80,6 +80,7 @@ struct completion };
static void completion_wait_dump( struct object*, int ); +static struct sync *completion_wait_get_sync( struct object * ); static int completion_wait_signaled( struct object *obj, struct wait_queue_entry *entry ); static void completion_wait_satisfied( struct object *obj, struct wait_queue_entry *entry ); static void completion_wait_destroy( struct object * ); @@ -99,6 +100,7 @@ static const struct object_ops completion_wait_ops = &no_type, /* type */ completion_wait_dump, /* dump */ no_get_fd, /* get_fd */ + completion_wait_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -115,7 +117,6 @@ static const struct object_ops completion_wait_ops = static void completion_wait_destroy( struct object *obj ) { struct completion_wait *wait = (struct completion_wait *)obj; - free( wait->msg ); }
@@ -127,6 +128,13 @@ static void completion_wait_dump( struct object *obj, int verbose ) fprintf( stderr, "Completion wait completion=%p\n", wait->completion ); }
+static struct sync *completion_wait_get_sync( struct object *obj ) +{ + struct completion_wait *wait = (struct completion_wait *)obj; + assert( obj->ops == &completion_wait_ops ); + return &wait->obj.sync; +} + static int completion_wait_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct completion_wait *wait = (struct completion_wait *)obj; @@ -158,6 +166,7 @@ static void completion_wait_satisfied( struct object *obj, struct wait_queue_ent }
static void completion_dump( struct object*, int ); +static struct sync *completion_get_sync( struct object * ); static int completion_signaled( struct object *obj, struct wait_queue_entry *entry ); static int completion_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); static void completion_destroy( struct object * ); @@ -177,6 +186,7 @@ static const struct object_ops completion_ops = &completion_type, /* type */ completion_dump, /* dump */ no_get_fd, /* get_fd */ + completion_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -209,6 +219,13 @@ static void completion_dump( struct object *obj, int verbose ) fprintf( stderr, "Completion depth=%u\n", completion->depth ); }
+static struct sync *completion_get_sync( struct object *obj ) +{ + struct completion *completion = (struct completion *)obj; + assert( obj->ops == &completion_ops ); + return &completion->obj.sync; +} + static int completion_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct completion *completion = (struct completion *)obj; diff --git a/server/console.c b/server/console.c index e0fb85e8cc5..8ee1690551b 100644 --- a/server/console.c +++ b/server/console.c @@ -70,6 +70,7 @@ static void console_dump( struct object *obj, int verbose ); static void console_destroy( struct object *obj ); static int console_signaled( struct object *obj, struct wait_queue_entry *entry ); static struct fd *console_get_fd( struct object *obj ); +static struct sync *console_get_sync( struct object *obj ); static struct object *console_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr, struct object *root ); static struct object *console_open_file( struct object *obj, unsigned int access, @@ -91,6 +92,7 @@ static const struct object_ops console_ops = &file_type, /* type */ console_dump, /* dump */ console_get_fd, /* get_fd */ + console_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -152,6 +154,7 @@ static void console_server_dump( struct object *obj, int verbose ); static void console_server_destroy( struct object *obj ); static int console_server_signaled( struct object *obj, struct wait_queue_entry *entry ); static struct fd *console_server_get_fd( struct object *obj ); +static struct sync *console_server_get_sync( struct object *obj ); static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr, struct object *root ); static struct object *console_server_open_file( struct object *obj, unsigned int access, @@ -172,6 +175,7 @@ static const struct object_ops console_server_ops = &file_type, /* type */ console_server_dump, /* dump */ console_server_get_fd, /* get_fd */ + console_server_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -227,6 +231,7 @@ static void screen_buffer_dump( struct object *obj, int verbose ); static void screen_buffer_destroy( struct object *obj ); static int screen_buffer_signaled( struct object *obj, struct wait_queue_entry *entry ); static struct fd *screen_buffer_get_fd( struct object *obj ); +static struct sync *screen_buffer_get_sync( struct object *obj ); static struct object *screen_buffer_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options );
@@ -245,6 +250,7 @@ static const struct object_ops screen_buffer_ops = &file_type, /* type */ screen_buffer_dump, /* dump */ screen_buffer_get_fd, /* get_fd */ + screen_buffer_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -289,6 +295,7 @@ static const struct object_ops console_device_ops = &device_type, /* type */ console_device_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -315,6 +322,7 @@ static int console_input_signaled( struct object *obj, struct wait_queue_entry * static struct object *console_input_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static struct fd *console_input_get_fd( struct object *obj ); +static struct sync *console_input_get_sync( struct object *obj ); static void console_input_destroy( struct object *obj );
static const struct sync_ops console_input_sync_ops = @@ -332,6 +340,7 @@ static const struct object_ops console_input_ops = &device_type, /* type */ console_input_dump, /* dump */ console_input_get_fd, /* get_fd */ + console_input_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -376,6 +385,7 @@ struct console_output static void console_output_dump( struct object *obj, int verbose ); static int console_output_signaled( struct object *obj, struct wait_queue_entry *entry ); static struct fd *console_output_get_fd( struct object *obj ); +static struct sync *console_output_get_sync( struct object *obj ); static struct object *console_output_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static void console_output_destroy( struct object *obj ); @@ -395,6 +405,7 @@ static const struct object_ops console_output_ops = &device_type, /* type */ console_output_dump, /* dump */ console_output_get_fd, /* get_fd */ + console_output_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -448,6 +459,7 @@ static const struct object_ops console_connection_ops = &device_type, /* type */ console_connection_dump, /* dump */ console_connection_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -509,6 +521,13 @@ static struct fd *console_get_fd( struct object *obj ) return (struct fd *)grab_object( console->fd ); }
+static struct sync *console_get_sync( struct object *obj ) +{ + struct console *console = (struct console *)obj; + assert( obj->ops == &console_ops ); + return &console->obj.sync; +} + static enum server_fd_type console_get_fd_type( struct fd *fd ) { return FD_TYPE_CHAR; @@ -888,6 +907,13 @@ static struct fd *screen_buffer_get_fd( struct object *obj ) return NULL; }
+static struct sync *screen_buffer_get_sync( struct object *obj ) +{ + struct screen_buffer *screen_buffer = (struct screen_buffer *)obj; + assert( obj->ops == &screen_buffer_ops ); + return &screen_buffer->obj.sync; +} + static void console_server_dump( struct object *obj, int verbose ) { assert( obj->ops == &console_server_ops ); @@ -954,6 +980,13 @@ static struct fd *console_server_get_fd( struct object* obj ) return (struct fd *)grab_object( server->fd ); }
+static struct sync *console_server_get_sync( struct object *obj ) +{ + struct console_server *server = (struct console_server *)obj; + assert( obj->ops == &console_server_ops ); + return &server->obj.sync; +} + static struct object *console_server_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ) { @@ -1449,6 +1482,13 @@ static struct fd *console_input_get_fd( struct object *obj ) return (struct fd *)grab_object( console_input->fd ); }
+static struct sync *console_input_get_sync( struct object *obj ) +{ + struct console_input *console_input = (struct console_input *)obj; + assert( obj->ops == &console_input_ops ); + return &console_input->obj.sync; +} + static struct object *console_input_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ) { @@ -1520,6 +1560,13 @@ static struct fd *console_output_get_fd( struct object *obj ) return (struct fd *)grab_object( console_output->fd ); }
+static struct sync *console_output_get_sync( struct object *obj ) +{ + struct console_output *console_output = (struct console_output *)obj; + assert( obj->ops == &console_output_ops ); + return &console_output->obj.sync; +} + static struct object *console_output_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ) { diff --git a/server/debugger.c b/server/debugger.c index 09c17712d17..8024556d77d 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -75,6 +75,7 @@ struct debug_obj
static void debug_event_dump( struct object *obj, int verbose ); +static struct sync *debug_event_get_sync( struct object *obj ); static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry ); static void debug_event_destroy( struct object *obj );
@@ -93,6 +94,7 @@ static const struct object_ops debug_event_ops = &no_type, /* type */ debug_event_dump, /* dump */ no_get_fd, /* get_fd */ + debug_event_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -107,6 +109,7 @@ static const struct object_ops debug_event_ops = };
static void debug_obj_dump( struct object *obj, int verbose ); +static struct sync *debug_obj_get_sync( struct object *obj ); static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entry ); static void debug_obj_destroy( struct object *obj );
@@ -125,6 +128,7 @@ static const struct object_ops debug_obj_ops = &debug_obj_type, /* type */ debug_obj_dump, /* dump */ no_get_fd, /* get_fd */ + debug_obj_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -307,6 +311,13 @@ static void debug_event_dump( struct object *obj, int verbose ) debug_event->sender, debug_event->data.code, debug_event->state ); }
+static struct sync *debug_event_get_sync( struct object *obj ) +{ + struct debug_event *debug_event = (struct debug_event *)obj; + assert( obj->ops == &debug_event_ops ); + return &debug_event->obj.sync; +} + static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct debug_event *debug_event = (struct debug_event *)obj; @@ -331,6 +342,13 @@ static void debug_obj_dump( struct object *obj, int verbose ) debug_obj->event_queue.next, debug_obj->event_queue.prev ); }
+static struct sync *debug_obj_get_sync( struct object *obj ) +{ + struct debug_obj *debug_obj = (struct debug_obj *)obj; + assert( obj->ops == &debug_obj_ops ); + return &debug_obj->obj.sync; +} + static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct debug_obj *debug_obj = (struct debug_obj *)obj; diff --git a/server/device.c b/server/device.c index 13a6728939b..85e448447a0 100644 --- a/server/device.c +++ b/server/device.c @@ -64,6 +64,7 @@ static const struct object_ops irp_call_ops = &no_type, /* type */ irp_call_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -90,6 +91,7 @@ struct device_manager };
static void device_manager_dump( struct object *obj, int verbose ); +static struct sync *device_manager_get_sync( struct object *obj ); static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry ); static void device_manager_destroy( struct object *obj );
@@ -108,6 +110,7 @@ static const struct object_ops device_manager_ops = &no_type, /* type */ device_manager_dump, /* dump */ no_get_fd, /* get_fd */ + device_manager_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -160,6 +163,7 @@ static const struct object_ops device_ops = &device_type, /* type */ device_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -207,6 +211,7 @@ static const struct object_ops device_file_ops = &file_type, /* type */ device_file_dump, /* dump */ device_file_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -418,7 +423,6 @@ static struct object *device_open_file( struct object *obj, unsigned int access, struct unicode_str nt_name;
if (!(file = alloc_object( &device_file_ops ))) return NULL; - file->obj.sync.ops = &default_fd_sync_ops; file->device = (struct device *)grab_object( device ); file->closed = 0; list_init( &file->kernel_object ); @@ -765,6 +769,13 @@ static void device_manager_dump( struct object *obj, int verbose ) fprintf( stderr, "Device manager\n" ); }
+static struct sync *device_manager_get_sync( struct object *obj ) +{ + struct device_manager *manager = (struct device_manager *)obj; + assert( obj->ops == &device_manager_ops ); + return &manager->obj.sync; +} + static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct device_manager *manager = (struct device_manager *)obj; diff --git a/server/directory.c b/server/directory.c index 6abd7e5c238..70f62263d35 100644 --- a/server/directory.c +++ b/server/directory.c @@ -67,6 +67,7 @@ static const struct object_ops object_type_ops = &objtype_type, /* type */ object_type_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -112,6 +113,7 @@ static const struct object_ops directory_ops = &directory_type, /* type */ directory_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 f9aa2d6244d..eeba7fcaf58 100644 --- a/server/event.c +++ b/server/event.c @@ -59,6 +59,7 @@ struct event };
static void event_dump( struct object *obj, int verbose ); +static struct sync *event_get_sync( struct object *obj ); 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); @@ -79,6 +80,7 @@ static const struct object_ops event_ops = &event_type, /* type */ event_dump, /* dump */ no_get_fd, /* get_fd */ + event_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -113,6 +115,7 @@ struct keyed_event };
static void keyed_event_dump( struct object *obj, int verbose ); +static struct sync *keyed_event_get_sync( struct object *obj ); static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *entry );
static const struct sync_ops keyed_event_sync_ops = @@ -130,6 +133,7 @@ static const struct object_ops keyed_event_ops = &keyed_event_type, /* type */ keyed_event_dump, /* dump */ no_get_fd, /* get_fd */ + keyed_event_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -197,6 +201,13 @@ static void event_dump( struct object *obj, int verbose ) event->manual_reset, event->signaled ); }
+static struct sync *event_get_sync( struct object *obj ) +{ + struct event *event = (struct event *)obj; + assert( obj->ops == &event_ops ); + return &event->obj.sync; +} + static int event_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct event *event = (struct event *)obj; @@ -258,6 +269,13 @@ static void keyed_event_dump( struct object *obj, int verbose ) fputs( "Keyed event\n", stderr ); }
+static struct sync *keyed_event_get_sync( struct object *obj ) +{ + struct keyed_event *event = (struct keyed_event *)obj; + assert( obj->ops == &keyed_event_ops ); + return &event->obj.sync; +} + static enum select_opcode matching_op( enum select_opcode op ) { return op ^ (SELECT_KEYED_EVENT_WAIT ^ SELECT_KEYED_EVENT_RELEASE); diff --git a/server/fd.c b/server/fd.c index b9366ee69e0..7859d9adbcd 100644 --- a/server/fd.c +++ b/server/fd.c @@ -157,14 +157,15 @@ struct fd };
static void fd_dump( struct object *obj, int verbose ); -static int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry ); +static struct sync *fd_get_sync( struct object *obj ); +static int fd_signaled( struct object *obj, struct wait_queue_entry *entry ); static void fd_destroy( struct object *obj );
-const struct sync_ops default_fd_sync_ops = +const struct sync_ops fd_sync_ops = { add_queue, /* add_queue */ remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ + fd_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ }; @@ -175,6 +176,7 @@ static const struct object_ops fd_ops = &no_type, /* type */ fd_dump, /* dump */ no_get_fd, /* get_fd */ + fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -211,6 +213,7 @@ static const struct object_ops device_ops = &no_type, /* type */ device_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -246,6 +249,7 @@ static const struct object_ops inode_ops = &no_type, /* type */ inode_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -275,6 +279,7 @@ struct file_lock };
static void file_lock_dump( struct object *obj, int verbose ); +static struct sync *file_lock_get_sync( struct object *obj ); static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry );
static const struct sync_ops file_lock_sync_ops = @@ -292,6 +297,7 @@ static const struct object_ops file_lock_ops = &no_type, /* type */ file_lock_dump, /* dump */ no_get_fd, /* get_fd */ + file_lock_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -1235,6 +1241,13 @@ static void file_lock_dump( struct object *obj, int verbose ) fprintf( stderr, "\n" ); }
+static struct sync *file_lock_get_sync( struct object *obj ) +{ + struct file_lock *lock = (struct file_lock *)obj; + assert( obj->ops == &file_lock_ops ); + return &lock->obj.sync; +} + static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct file_lock *lock = (struct file_lock *)obj; @@ -1560,6 +1573,12 @@ static void fd_dump( struct object *obj, int verbose ) fprintf( stderr, "\n" ); }
+static struct sync *fd_get_sync( struct object *obj ) +{ + struct fd *fd = (struct fd *)obj; + return &fd->obj.sync; +} + static void fd_destroy( struct object *obj ) { struct fd *fd = (struct fd *)obj; @@ -1679,10 +1698,10 @@ static inline void unmount_fd( struct fd *fd ) /* allocate an fd object, without setting the unix fd yet */ static struct fd *alloc_fd_object(void) { - struct fd *fd = alloc_object( &fd_ops ); - - if (!fd) return NULL; + struct fd *fd;
+ if (!(fd = alloc_object( &fd_ops ))) return NULL; + fd->obj.sync.ops = &fd_sync_ops; fd->fd_ops = NULL; fd->user = NULL; fd->inode = NULL; @@ -1719,10 +1738,10 @@ static struct fd *alloc_fd_object(void) /* allocate a pseudo fd object, for objects that need to behave like files but don't have a unix fd */ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *user, unsigned int options ) { - struct fd *fd = alloc_object( &fd_ops ); - - if (!fd) return NULL; + struct fd *fd;
+ if (!(fd = alloc_object( &fd_ops ))) return NULL; + fd->obj.sync.ops = &fd_sync_ops; fd->fd_ops = fd_user_ops; fd->user = user; fd->inode = NULL; @@ -2152,7 +2171,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) */ @@ -2169,13 +2188,20 @@ int check_fd_events( struct fd *fd, int events ) return pfd.revents; }
-/* default signaled() routine for objects that poll() on an fd */ -static 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 sync *default_fd_get_sync( struct object *obj ) { struct fd *fd = get_obj_fd( obj ); - int ret = fd->signaled; + struct sync *sync = &fd->obj.sync; 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 666b1a6f55e..d1d695b934c 100644 --- a/server/file.c +++ b/server/file.c @@ -92,6 +92,7 @@ static const struct object_ops file_ops = &file_type, /* type */ file_dump, /* dump */ file_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ file_get_sd, /* get_sd */ file_set_sd, /* set_sd */ @@ -140,7 +141,6 @@ struct file *create_file_for_fd( int fd, unsigned int access, unsigned int shari close( fd ); return NULL; } - file->obj.sync.ops = &default_fd_sync_ops; file->mode = st.st_mode; file->access = default_map_access( &file->obj, access ); list_init( &file->kernel_object ); @@ -168,7 +168,6 @@ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigne
if ((file = alloc_object( &file_ops ))) { - file->obj.sync.ops = &default_fd_sync_ops; file->mode = st.st_mode; file->access = default_map_access( &file->obj, access ); list_init( &file->kernel_object ); @@ -187,7 +186,6 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_ struct file *file;
if (!(file = alloc_object( &file_ops ))) return NULL; - file->obj.sync.ops = &default_fd_sync_ops; file->access = access; file->mode = mode; file->uid = ~(uid_t)0; diff --git a/server/file.h b/server/file.h index 66a67ec4a16..06622c40783 100644 --- a/server/file.h +++ b/server/file.h @@ -109,6 +109,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 struct sync *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 ); @@ -132,8 +133,6 @@ extern void remove_process_locks( struct process *process );
static inline struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get_fd( obj ); }
-extern const struct sync_ops default_fd_sync_ops; - /* timeout functions */
struct timeout_user; diff --git a/server/handle.c b/server/handle.c index 39dad955ed2..38d9f87b5a3 100644 --- a/server/handle.c +++ b/server/handle.c @@ -124,6 +124,7 @@ static const struct object_ops handle_table_ops = &no_type, /* type */ handle_table_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 45e185f9896..2cc321310f4 100644 --- a/server/hook.c +++ b/server/hook.c @@ -79,6 +79,7 @@ static const struct object_ops hook_table_ops = &no_type, /* type */ hook_table_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 3d338b06e71..5970af120f5 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -79,6 +79,7 @@ static const struct object_ops mailslot_ops = &file_type, /* type */ mailslot_dump, /* dump */ mailslot_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ mailslot_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -135,6 +136,7 @@ static const struct object_ops mail_writer_ops = &file_type, /* type */ mail_writer_dump, /* dump */ mail_writer_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ mail_writer_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -195,6 +197,7 @@ static const struct object_ops mailslot_device_ops = &device_type, /* type */ mailslot_device_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -220,6 +223,7 @@ static const struct object_ops mailslot_device_file_ops = &file_type, /* type */ mailslot_device_file_dump, /* dump */ mailslot_device_file_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -463,7 +467,6 @@ static struct object *mailslot_device_open_file( struct object *obj, unsigned in struct mailslot_device_file *file;
if (!(file = alloc_object( &mailslot_device_file_ops ))) return NULL; - file->obj.sync.ops = &default_fd_sync_ops; file->device = (struct mailslot_device *)grab_object( obj ); if (!(file->fd = alloc_pseudo_fd( &mailslot_device_fd_ops, obj, options ))) { @@ -539,7 +542,6 @@ static struct mailslot *create_mailslot( struct object *root, struct mailslot *mailslot;
if (!(mailslot = create_named_object( root, &mailslot_ops, name, attr & ~OBJ_OPENIF, sd ))) return NULL; - mailslot->obj.sync.ops = &default_fd_sync_ops; mailslot->fd = NULL; mailslot->max_msgsize = max_msgsize; mailslot->read_timeout = read_timeout; diff --git a/server/mapping.c b/server/mapping.c index a755577a77f..6fb2d4f3a01 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -65,6 +65,7 @@ static const struct object_ops ranges_ops = &no_type, /* type */ ranges_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -96,6 +97,7 @@ static const struct object_ops shared_map_ops = &no_type, /* type */ shared_map_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -164,6 +166,7 @@ static const struct object_ops mapping_ops = &mapping_type, /* type */ mapping_dump, /* dump */ mapping_get_fd, /* get_fd */ + no_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 5b7184e6913..f2ddbe9cc1e 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -60,6 +60,7 @@ struct mutex };
static void mutex_dump( struct object *obj, int verbose ); +static struct sync *mutex_get_sync( struct object *obj ); static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry ); static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry ); static void mutex_destroy( struct object *obj ); @@ -80,6 +81,7 @@ static const struct object_ops mutex_ops = &mutex_type, /* type */ mutex_dump, /* dump */ no_get_fd, /* get_fd */ + mutex_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -158,6 +160,13 @@ static void mutex_dump( struct object *obj, int verbose ) fprintf( stderr, "Mutex count=%u owner=%p\n", mutex->count, mutex->owner ); }
+static struct sync *mutex_get_sync( struct object *obj ) +{ + struct mutex *mutex = (struct mutex *)obj; + assert( obj->ops == &mutex_ops ); + return &mutex->obj.sync; +} + static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct mutex *mutex = (struct mutex *)obj; diff --git a/server/named_pipe.c b/server/named_pipe.c index a281e908fe6..88f17f74713 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -117,6 +117,7 @@ static const struct object_ops named_pipe_ops = &no_type, /* type */ named_pipe_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ named_pipe_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -160,6 +161,7 @@ static const struct object_ops pipe_server_ops = &file_type, /* type */ pipe_server_dump, /* dump */ pipe_end_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ pipe_end_get_sd, /* get_sd */ pipe_end_set_sd, /* set_sd */ @@ -199,6 +201,7 @@ static const struct object_ops pipe_client_ops = &file_type, /* type */ pipe_client_dump, /* dump */ pipe_end_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ pipe_end_get_sd, /* get_sd */ pipe_end_set_sd, /* set_sd */ @@ -241,6 +244,7 @@ static const struct object_ops named_pipe_device_ops = &device_type, /* type */ named_pipe_device_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -267,6 +271,7 @@ static const struct object_ops named_pipe_device_file_ops = &file_type, /* type */ named_pipe_device_file_dump, /* dump */ named_pipe_device_file_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -312,6 +317,7 @@ static const struct object_ops named_pipe_dir_ops = &file_type, /* type */ named_pipe_dir_dump, /* dump */ named_pipe_dir_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -527,7 +533,6 @@ static struct object *named_pipe_device_lookup_name( struct object *obj, struct struct named_pipe_device_file *dir;
if (!(dir = alloc_object( &named_pipe_dir_ops ))) return NULL; - dir->obj.sync.ops = &default_fd_sync_ops; dir->fd = NULL; /* defer alloc_pseudo_fd() until after we have options */ dir->device = (struct named_pipe_device *)grab_object( obj );
@@ -546,7 +551,6 @@ static struct object *named_pipe_device_open_file( struct object *obj, unsigned struct named_pipe_device_file *file;
if (!(file = alloc_object( &named_pipe_device_file_ops ))) return NULL; - file->obj.sync.ops = &default_fd_sync_ops; file->device = (struct named_pipe_device *)grab_object( obj ); if (!(file->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, obj, options ))) { @@ -1378,7 +1382,6 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned struct pipe_server *server;
if (!(server = alloc_object( &pipe_server_ops ))) return NULL; - server->pipe_end.obj.sync.ops = &default_fd_sync_ops; server->options = options; init_pipe_end( &server->pipe_end, pipe, pipe_flags, pipe->insize ); server->pipe_end.state = FILE_PIPE_LISTENING_STATE; @@ -1402,7 +1405,6 @@ static struct pipe_end *create_pipe_client( struct named_pipe *pipe, data_size_t struct pipe_end *client;
if (!(client = alloc_object( &pipe_client_ops ))) return NULL; - client->obj.sync.ops = &default_fd_sync_ops; init_pipe_end( client, pipe, 0, buffer_size ); client->state = FILE_PIPE_CONNECTED_STATE; client->client_pid = get_process_id( current->process ); diff --git a/server/object.c b/server/object.c index 70f83870bf7..302bbb53523 100644 --- a/server/object.c +++ b/server/object.c @@ -106,6 +106,7 @@ static const struct object_ops apc_reserve_ops = &apc_reserve_type, /* type */ dump_reserve, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -125,6 +126,7 @@ static const struct object_ops completion_reserve_ops = &completion_reserve_type, /* type */ dump_reserve, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -294,6 +296,11 @@ static const struct sync_ops no_sync_ops = no_signal, /* signal */ };
+static struct sync no_sync = +{ + &no_sync_ops, +}; + /* allocate and initialize an object */ void *alloc_object( const struct object_ops *ops ) { @@ -639,6 +646,11 @@ struct fd *no_get_fd( struct object *obj ) return NULL; }
+struct sync *no_get_sync( struct object *obj ) +{ + return &no_sync; +} + 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 199ce98ed65..3db4f3d56cb 100644 --- a/server/object.h +++ b/server/object.h @@ -94,6 +94,8 @@ struct object_ops void (*dump)(struct object *,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 sync *(*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 */ @@ -181,6 +183,7 @@ 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 sync *no_get_sync( struct object *obj ); extern unsigned int default_map_access( struct object *obj, unsigned int access ); extern struct security_descriptor *default_get_sd( struct object *obj ); 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 19ece8c56c4..eac2df227c9 100644 --- a/server/process.c +++ b/server/process.c @@ -89,6 +89,7 @@ struct type_descr process_type = };
static void process_dump( struct object *obj, int verbose ); +static struct sync *process_get_sync( struct object *obj ); static int process_signaled( struct object *obj, struct wait_queue_entry *entry ); static unsigned int process_map_access( struct object *obj, unsigned int access ); static struct security_descriptor *process_get_sd( struct object *obj ); @@ -112,6 +113,7 @@ static const struct object_ops process_ops = &process_type, /* type */ process_dump, /* dump */ no_get_fd, /* get_fd */ + process_get_sync, /* get_sync */ process_map_access, /* map_access */ process_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -149,6 +151,7 @@ struct startup_info };
static void startup_info_dump( struct object *obj, int verbose ); +static struct sync *startup_info_get_sync( struct object *obj ); static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry ); static void startup_info_destroy( struct object *obj );
@@ -167,6 +170,7 @@ static const struct object_ops startup_info_ops = &no_type, /* type */ startup_info_dump, /* dump */ no_get_fd, /* get_fd */ + startup_info_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -197,6 +201,7 @@ struct type_descr job_type = };
static void job_dump( struct object *obj, int verbose ); +static struct sync *job_get_sync( struct object *obj ); static int job_signaled( struct object *obj, struct wait_queue_entry *entry ); static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); static void job_destroy( struct object *obj ); @@ -232,6 +237,7 @@ static const struct object_ops job_ops = &job_type, /* type */ job_dump, /* dump */ no_get_fd, /* get_fd */ + job_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -462,6 +468,13 @@ static void job_dump( struct object *obj, int verbose ) list_count(&job->process_list), list_count(&job->child_job_list), job->parent ); }
+static struct sync *job_get_sync( struct object *obj ) +{ + struct job *job = (struct job *)obj; + assert( obj->ops == &job_ops ); + return &job->obj.sync; +} + static int job_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct job *job = (struct job *)obj; @@ -809,6 +822,13 @@ static void process_dump( struct object *obj, int verbose ) fprintf( stderr, "Process id=%04x handles=%p\n", process->id, process->handles ); }
+static struct sync *process_get_sync( struct object *obj ) +{ + struct process *process = (struct process *)obj; + assert( obj->ops == &process_ops ); + return &process->obj.sync; +} + static int process_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct process *process = (struct process *)obj; @@ -899,6 +919,13 @@ static void startup_info_dump( struct object *obj, int verbose ) fputc( '\n', stderr ); }
+static struct sync *startup_info_get_sync( struct object *obj ) +{ + struct startup_info *info = (struct startup_info *)obj; + assert( obj->ops == &startup_info_ops ); + return &info->obj.sync; +} + static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct startup_info *info = (struct startup_info *)obj; diff --git a/server/queue.c b/server/queue.c index 7146ee51a2c..f607fafa882 100644 --- a/server/queue.c +++ b/server/queue.c @@ -147,6 +147,7 @@ struct hotkey };
static void msg_queue_dump( struct object *obj, int verbose ); +static struct sync *msg_queue_get_sync( struct object *obj ); static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry ); static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry ); static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry ); @@ -172,6 +173,7 @@ static const struct object_ops msg_queue_ops = &no_type, /* type */ msg_queue_dump, /* dump */ no_get_fd, /* get_fd */ + msg_queue_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -204,6 +206,7 @@ static const struct object_ops thread_input_ops = &no_type, /* type */ thread_input_dump, /* dump */ no_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -1305,6 +1308,13 @@ static void msg_queue_dump( struct object *obj, int verbose ) queue_shm->wake_bits, queue_shm->wake_mask ); }
+static struct sync *msg_queue_get_sync( struct object *obj ) +{ + struct msg_queue *queue = (struct msg_queue *)obj; + assert( obj->ops == &msg_queue_ops ); + return &queue->obj.sync; +} + static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; diff --git a/server/registry.c b/server/registry.c index bd80d3e7399..169833f53e6 100644 --- a/server/registry.c +++ b/server/registry.c @@ -178,6 +178,7 @@ static const struct object_ops key_ops = &key_type, /* type */ key_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 474750523bf..83ecdff286e 100644 --- a/server/request.c +++ b/server/request.c @@ -87,6 +87,7 @@ static const struct object_ops master_socket_ops = &no_type, /* type */ master_socket_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 7c7de0f77f7..3ac9ff23a2d 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -58,6 +58,7 @@ struct semaphore };
static void semaphore_dump( struct object *obj, int verbose ); +static struct sync *semaphore_get_sync( struct object *obj ); static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry ); static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ); static int semaphore_signal( struct object *obj, unsigned int access ); @@ -77,6 +78,7 @@ static const struct object_ops semaphore_ops = &semaphore_type, /* type */ semaphore_dump, /* dump */ no_get_fd, /* get_fd */ + semaphore_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -144,6 +146,13 @@ static void semaphore_dump( struct object *obj, int verbose ) fprintf( stderr, "Semaphore count=%d max=%d\n", sem->count, sem->max ); }
+static struct sync *semaphore_get_sync( struct object *obj ) +{ + struct semaphore *semaphore = (struct semaphore *)obj; + assert( obj->ops == &semaphore_ops ); + return &semaphore->obj.sync; +} + static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct semaphore *sem = (struct semaphore *)obj; diff --git a/server/serial.c b/server/serial.c index aedc962174a..5f29dff7948 100644 --- a/server/serial.c +++ b/server/serial.c @@ -89,6 +89,7 @@ static const struct object_ops serial_ops = &file_type, /* type */ serial_dump, /* dump */ serial_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -132,7 +133,6 @@ struct object *create_serial( struct fd *fd ) struct serial *serial;
if (!(serial = alloc_object( &serial_ops ))) return NULL; - serial->obj.sync.ops = &default_fd_sync_ops; serial->read_timer = NULL; serial->eventmask = 0; serial->pending_write = 0; diff --git a/server/signal.c b/server/signal.c index 8016c507367..6b18d5f2412 100644 --- a/server/signal.c +++ b/server/signal.c @@ -60,6 +60,7 @@ static const struct object_ops handler_ops = &no_type, /* type */ handler_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 4dd973ae7d8..fc7a181534e 100644 --- a/server/sock.c +++ b/server/sock.c @@ -484,6 +484,7 @@ static const struct object_ops sock_ops = &file_type, /* type */ sock_dump, /* dump */ sock_get_fd, /* get_fd */ + default_fd_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -1777,7 +1778,6 @@ static struct sock *create_socket(void) struct sock *sock;
if (!(sock = alloc_object( &sock_ops ))) return NULL; - sock->obj.sync.ops = &default_fd_sync_ops; sock->fd = NULL; sock->state = SOCK_UNCONNECTED; sock->mask = 0; @@ -3689,6 +3689,7 @@ static const struct object_ops ifchange_ops = &no_type, /* type */ ifchange_dump, /* dump */ ifchange_get_fd, /* get_fd */ + no_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -3905,6 +3906,7 @@ static const struct object_ops socket_device_ops = &device_type, /* type */ socket_device_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 125130fc90c..391facc355f 100644 --- a/server/symlink.c +++ b/server/symlink.c @@ -69,6 +69,7 @@ static const struct object_ops symlink_ops = &symlink_type, /* type */ symlink_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 ea4432ec6a6..5100045b7f2 100644 --- a/server/thread.c +++ b/server/thread.c @@ -94,6 +94,7 @@ struct thread_apc };
static void dump_thread_apc( struct object *obj, int verbose ); +static struct sync *thread_apc_get_sync( struct object *obj ); static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry ); static void thread_apc_destroy( struct object *obj ); static void clear_apc_queue( struct list *queue ); @@ -113,6 +114,7 @@ static const struct object_ops thread_apc_ops = &no_type, /* type */ dump_thread_apc, /* dump */ no_get_fd, /* get_fd */ + thread_apc_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -142,6 +144,7 @@ struct context static const unsigned int system_flags = SERVER_CTX_DEBUG_REGISTERS;
static void dump_context( struct object *obj, int verbose ); +static struct sync *context_get_sync( struct object *obj ); static int context_signaled( struct object *obj, struct wait_queue_entry *entry );
static const struct sync_ops context_sync_ops = @@ -159,6 +162,7 @@ static const struct object_ops context_ops = &no_type, /* type */ dump_context, /* dump */ no_get_fd, /* get_fd */ + context_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -191,6 +195,7 @@ struct type_descr thread_type = };
static void dump_thread( struct object *obj, int verbose ); +static struct sync *thread_get_sync( struct object *obj ); static int thread_signaled( struct object *obj, struct wait_queue_entry *entry ); static unsigned int thread_map_access( struct object *obj, unsigned int access ); static void thread_poll_event( struct fd *fd, int event ); @@ -212,6 +217,7 @@ static const struct object_ops thread_ops = &thread_type, /* type */ dump_thread, /* dump */ no_get_fd, /* get_fd */ + thread_get_sync, /* get_sync */ thread_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -459,6 +465,13 @@ static void dump_context( struct object *obj, int verbose ) context->regs[CTX_NATIVE].flags, context->regs[CTX_WOW].flags ); }
+static struct sync *context_get_sync( struct object *obj ) +{ + struct context *context = (struct context *)obj; + assert( obj->ops == &context_ops ); + return &context->obj.sync; +} +
static int context_signaled( struct object *obj, struct wait_queue_entry *entry ) { @@ -647,6 +660,13 @@ static void dump_thread( struct object *obj, int verbose ) thread->id, thread->unix_pid, thread->unix_tid, thread->state ); }
+static struct sync *thread_get_sync( struct object *obj ) +{ + struct thread *thread = (struct thread *)obj; + assert( obj->ops == &thread_ops ); + return &thread->obj.sync; +} + static int thread_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct thread *mythread = (struct thread *)obj; @@ -669,6 +689,13 @@ static void dump_thread_apc( struct object *obj, int verbose ) fprintf( stderr, "APC owner=%p type=%u\n", apc->owner, apc->call.type ); }
+static struct sync *thread_apc_get_sync( struct object *obj ) +{ + struct thread_apc *apc = (struct thread_apc *)obj; + assert( obj->ops == &thread_apc_ops ); + return &apc->obj.sync; +} + static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct thread_apc *apc = (struct thread_apc *)obj; @@ -975,6 +1002,36 @@ void set_wait_status( struct wait_queue_entry *entry, int status ) entry->wait->status = status; }
+static void sync_satisfied( struct sync *sync, struct wait_queue_entry *entry ) +{ + struct object *obj = CONTAINING_RECORD( sync, struct object, sync ); + sync->ops->satisfied( obj, entry ); +} + +static void sync_remove_queue( struct sync *sync, struct wait_queue_entry *entry ) +{ + struct object *obj = CONTAINING_RECORD( sync, struct object, sync ); + sync->ops->remove_queue( obj, entry ); +} + +static int sync_add_queue( struct sync *sync, struct wait_queue_entry *entry ) +{ + struct object *obj = CONTAINING_RECORD( sync, struct object, sync ); + return sync->ops->add_queue( obj, entry ); +} + +static int sync_signaled( struct sync *sync, struct wait_queue_entry *entry ) +{ + struct object *obj = CONTAINING_RECORD( sync, struct object, sync ); + return sync->ops->signaled( obj, entry ); +} + +static int sync_signal( struct sync *sync, unsigned int access ) +{ + struct object *obj = CONTAINING_RECORD( sync, struct object, sync ); + return sync->ops->signal( obj, access ); +} + /* finish waiting */ static unsigned int end_wait( struct thread *thread, unsigned int status ) { @@ -991,18 +1048,26 @@ 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->sync.ops->satisfied( entry->obj, entry ); + { + struct sync *sync = entry->obj->ops->get_sync( entry->obj ); + sync_satisfied( sync, entry ); + } } else { + struct sync *sync; entry = wait->queues + status; - entry->obj->sync.ops->satisfied( entry->obj, entry ); + sync = entry->obj->ops->get_sync( entry->obj ); + sync_satisfied( sync, 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->sync.ops->remove_queue( entry->obj, entry ); + { + struct sync *sync = entry->obj->ops->get_sync( entry->obj ); + sync_remove_queue( sync, entry ); + } if (wait->user) remove_timeout_user( wait->user ); free( wait ); return status; @@ -1031,8 +1096,9 @@ static int wait_on( const union select_op *select_op, unsigned int count, struct for (i = 0, entry = wait->queues; i < count; i++, entry++) { struct object *obj = objects[i]; + struct sync *sync = obj->ops->get_sync( obj ); entry->wait = wait; - if (!obj->sync.ops->add_queue( obj, entry )) + if (!sync_add_queue( sync, entry )) { wait->count = i; end_wait( current, get_error() ); @@ -1086,13 +1152,19 @@ 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->sync.ops->signaled( entry->obj, entry ); + { + struct sync *sync = entry->obj->ops->get_sync( entry->obj ); + not_ok |= !sync_signaled( sync, entry ); + } if (!not_ok) return STATUS_WAIT_0; } else { for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) - if (entry->obj->sync.ops->signaled( entry->obj, entry )) return i; + { + struct sync *sync = entry->obj->ops->get_sync( entry->obj ); + if (sync_signaled( sync, entry )) return i; + } }
if ((wait->flags & SELECT_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC; @@ -1208,7 +1280,8 @@ static int signal_object( obj_handle_t handle ) obj = get_handle_obj( current->process, handle, 0, NULL ); if (obj) { - ret = obj->sync.ops->signal( obj, get_handle_access( current->process, handle )); + struct sync *sync = obj->ops->get_sync( obj ); + ret = sync_signal( sync, get_handle_access( current->process, handle ) ); release_object( obj ); } return ret; diff --git a/server/timer.c b/server/timer.c index c82845cf80f..50cb7a618e5 100644 --- a/server/timer.c +++ b/server/timer.c @@ -64,6 +64,7 @@ struct timer };
static void timer_dump( struct object *obj, int verbose ); +static struct sync *timer_get_sync( struct object *obj ); static int timer_signaled( struct object *obj, struct wait_queue_entry *entry ); static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry ); static void timer_destroy( struct object *obj ); @@ -83,6 +84,7 @@ static const struct object_ops timer_ops = &timer_type, /* type */ timer_dump, /* dump */ no_get_fd, /* get_fd */ + timer_get_sync, /* get_sync */ default_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ @@ -206,6 +208,13 @@ static void timer_dump( struct object *obj, int verbose ) timer->manual, get_timeout_str(timeout), timer->period ); }
+static struct sync *timer_get_sync( struct object *obj ) +{ + struct timer *timer = (struct timer *)obj; + assert( obj->ops == &timer_ops ); + return &timer->obj.sync; +} + static int timer_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct timer *timer = (struct timer *)obj; diff --git a/server/token.c b/server/token.c index e7a975ae793..4f90a673f8e 100644 --- a/server/token.c +++ b/server/token.c @@ -143,6 +143,7 @@ static const struct object_ops token_ops = &token_type, /* type */ token_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 da215ab5b78..1d8bf258d02 100644 --- a/server/window.c +++ b/server/window.c @@ -105,6 +105,7 @@ static const struct object_ops window_ops = &no_type, /* type */ window_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 5b33abb257f..019c2fc810c 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -74,6 +74,7 @@ static const struct object_ops winstation_ops = &winstation_type, /* type */ winstation_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 desktop_ops = &desktop_type, /* type */ desktop_dump, /* dump */ no_get_fd, /* get_fd */ + no_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 | 22 ++++++++++++++++++++++ server/fd.c | 34 ++++++++-------------------------- server/object.h | 2 ++ 3 files changed, 32 insertions(+), 26 deletions(-)
diff --git a/server/event.c b/server/event.c index eeba7fcaf58..7cb715d06ad 100644 --- a/server/event.c +++ b/server/event.c @@ -54,6 +54,7 @@ struct event { struct object obj; /* object header */ struct list kernel_object; /* list of kernel object pointers */ + int internal; /* event is an internal sync */ int manual_reset; /* is it a manual reset event? */ int signaled; /* event has been signaled */ }; @@ -161,6 +162,7 @@ struct event *create_event( struct object *root, const struct unicode_str *name, /* initialize it if it didn't already exist */ event->obj.sync.ops = &event_sync_ops; list_init( &event->kernel_object ); + event->internal = 0; event->manual_reset = manual_reset; event->signaled = initial_state; } @@ -168,6 +170,16 @@ struct event *create_event( struct object *root, const struct unicode_str *name, return event; }
+/* create a wineserver internal event for sync purposes */ +struct event *create_event_sync( int manual, int signaled ) +{ + struct event *event; + event = create_event( NULL, NULL, 0, manual, signaled, NULL ); + assert( event ); + event->internal = 1; + return event; +} + struct event *get_event_obj( struct process *process, obj_handle_t handle, unsigned int access ) { return (struct event *)get_handle_obj( process, handle, access, &event_ops ); @@ -193,6 +205,11 @@ void reset_event( struct event *event ) event->signaled = 0; }
+struct sync *get_event_sync( struct event *event ) +{ + return &event->obj.sync; +} + static void event_dump( struct object *obj, int verbose ) { struct event *event = (struct event *)obj; @@ -228,6 +245,11 @@ static int event_signal( struct object *obj, unsigned int access ) struct event *event = (struct event *)obj; assert( obj->ops == &event_ops );
+ if (event->internal) + { + set_error( STATUS_OBJECT_TYPE_MISMATCH ); + return 0; + } if (!(access & EVENT_MODIFY_STATE)) { set_error( STATUS_ACCESS_DENIED ); diff --git a/server/fd.c b/server/fd.c index 7859d9adbcd..9005c2803d2 100644 --- a/server/fd.c +++ b/server/fd.c @@ -128,6 +128,7 @@ struct closed_fd struct fd { struct object obj; /* object header */ + struct event *sync; /* event object as sync */ 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 */ @@ -158,18 +158,8 @@ struct fd
static void fd_dump( struct object *obj, int verbose ); static struct sync *fd_get_sync( struct object *obj ); -static int fd_signaled( struct object *obj, struct wait_queue_entry *entry ); static void fd_destroy( struct object *obj );
-const struct sync_ops fd_sync_ops = -{ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - fd_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ -}; - static const struct object_ops fd_ops = { sizeof(struct fd), /* size */ @@ -1576,7 +1566,7 @@ static void fd_dump( struct object *obj, int verbose ) static struct sync *fd_get_sync( struct object *obj ) { struct fd *fd = (struct fd *)obj; - return &fd->obj.sync; + return get_event_sync( fd->sync ); }
static void fd_destroy( struct object *obj ) @@ -1603,6 +1593,7 @@ static void fd_destroy( struct object *obj ) if (fd->unix_fd != -1) close( fd->unix_fd ); free( fd->unix_name ); } + release_object( fd->sync ); }
/* check if the desired access is possible without violating */ @@ -1701,7 +1692,7 @@ static struct fd *alloc_fd_object(void) struct fd *fd;
if (!(fd = alloc_object( &fd_ops ))) return NULL; - fd->obj.sync.ops = &fd_sync_ops; + fd->sync = create_event_sync( 1, 1 ); fd->fd_ops = NULL; fd->user = NULL; fd->inode = NULL; @@ -1716,7 +1707,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; @@ -1741,7 +1731,7 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use struct fd *fd;
if (!(fd = alloc_object( &fd_ops ))) return NULL; - fd->obj.sync.ops = &fd_sync_ops; + fd->sync = create_event_sync( 1, 1 ); fd->fd_ops = fd_user_ops; fd->user = user; fd->inode = NULL; @@ -1756,7 +1746,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; @@ -2170,8 +2159,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) set_event( fd->sync ); + else reset_event( fd->sync ); }
/* check if events are pending and if yes return which one(s) */ @@ -2188,18 +2177,11 @@ 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 sync *default_fd_get_sync( struct object *obj ) { struct fd *fd = get_obj_fd( obj ); - struct sync *sync = &fd->obj.sync; + struct sync *sync = get_event_sync( fd->sync ); release_object( fd ); return sync; } diff --git a/server/object.h b/server/object.h index 3db4f3d56cb..26f50423197 100644 --- a/server/object.h +++ b/server/object.h @@ -231,12 +231,14 @@ struct keyed_event; 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 ); +extern struct event *create_event_sync( int manual, int signaled ); extern struct keyed_event *create_keyed_event( struct object *root, const struct unicode_str *name, unsigned int attr, const struct security_descriptor *sd ); extern struct event *get_event_obj( struct process *process, obj_handle_t handle, unsigned int access ); extern struct keyed_event *get_keyed_event_obj( struct process *process, obj_handle_t handle, unsigned int access ); extern void set_event( struct event *event ); extern void reset_event( struct event *event ); +extern struct sync *get_event_sync( struct event *event );
/* mutex functions */
From: Rémi Bernon rbernon@codeweavers.com
--- server/thread.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/server/thread.c b/server/thread.c index 5100045b7f2..6f99b8c0415 100644 --- a/server/thread.c +++ b/server/thread.c @@ -85,6 +85,7 @@ struct thread_wait struct thread_apc { struct object obj; /* object header */ + struct event *sync; /* event object as sync */ struct list entry; /* queue linked list */ struct thread *caller; /* thread that queued this apc */ struct object *owner; /* object that queued this apc */ @@ -95,19 +96,9 @@ struct thread_apc
static void dump_thread_apc( struct object *obj, int verbose ); static struct sync *thread_apc_get_sync( struct object *obj ); -static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry ); static void thread_apc_destroy( struct object *obj ); static void clear_apc_queue( struct list *queue );
-static const struct sync_ops thread_apc_sync_ops = -{ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - thread_apc_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ -}; - static const struct object_ops thread_apc_ops = { sizeof(struct thread_apc), /* size */ @@ -693,13 +684,7 @@ static struct sync *thread_apc_get_sync( struct object *obj ) { struct thread_apc *apc = (struct thread_apc *)obj; assert( obj->ops == &thread_apc_ops ); - return &apc->obj.sync; -} - -static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry ) -{ - struct thread_apc *apc = (struct thread_apc *)obj; - return apc->executed; + return get_event_sync( apc->sync ); }
static void thread_apc_destroy( struct object *obj ) @@ -715,6 +700,7 @@ static void thread_apc_destroy( struct object *obj ) async_set_result( apc->owner, apc->call.async_io.status, 0 ); release_object( apc->owner ); } + release_object( apc->sync ); }
/* queue an async procedure call */ @@ -724,7 +710,7 @@ static struct thread_apc *create_apc( struct object *owner, const union apc_call
if ((apc = alloc_object( &thread_apc_ops ))) { - apc->obj.sync.ops = &thread_apc_sync_ops; + apc->sync = create_event_sync( 1, 0 ); if (call_data) apc->call = *call_data; else apc->call.type = APC_NONE; apc->caller = NULL; @@ -1486,7 +1472,7 @@ void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_ty if (apc->owner != owner) continue; list_remove( &apc->entry ); apc->executed = 1; - wake_up( &apc->obj, 0 ); + set_event( apc->sync ); release_object( apc ); return; } @@ -1516,7 +1502,7 @@ static void clear_apc_queue( struct list *queue ) struct thread_apc *apc = LIST_ENTRY( ptr, struct thread_apc, entry ); list_remove( &apc->entry ); apc->executed = 1; - wake_up( &apc->obj, 0 ); + set_event( apc->sync ); release_object( apc ); } } @@ -1976,7 +1962,7 @@ DECL_HANDLER(select) apc->result.create_thread.handle = handle; clear_error(); /* ignore errors from the above calls */ } - wake_up( &apc->obj, 0 ); + set_event( apc->sync ); close_handle( current->process, req->prev_apc ); release_object( apc ); } @@ -1999,7 +1985,7 @@ DECL_HANDLER(select) else { apc->executed = 1; - wake_up( &apc->obj, 0 ); + set_event( apc->sync ); } release_object( apc ); }
From: Rémi Bernon rbernon@codeweavers.com
--- server/thread.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-)
diff --git a/server/thread.c b/server/thread.c index 6f99b8c0415..a418100d9e0 100644 --- a/server/thread.c +++ b/server/thread.c @@ -125,6 +125,7 @@ static const struct object_ops thread_apc_ops = struct context { struct object obj; /* object header */ + struct event *sync; /* event object as sync */ unsigned int status; /* status of the context */ struct context_data regs[2];/* context data */ }; @@ -136,16 +137,7 @@ static const unsigned int system_flags = SERVER_CTX_DEBUG_REGISTERS;
static void dump_context( struct object *obj, int verbose ); static struct sync *context_get_sync( struct object *obj ); -static int context_signaled( struct object *obj, struct wait_queue_entry *entry ); - -static const struct sync_ops context_sync_ops = -{ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - context_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ -}; +static void context_destroy( struct object *obj );
static const struct object_ops context_ops = { @@ -164,7 +156,7 @@ static const struct object_ops context_ops = no_open_file, /* open_file */ no_kernel_obj_list, /* get_kernel_obj_list */ no_close_handle, /* close_handle */ - no_destroy /* destroy */ + context_destroy /* destroy */ };
@@ -460,22 +452,21 @@ static struct sync *context_get_sync( struct object *obj ) { struct context *context = (struct context *)obj; assert( obj->ops == &context_ops ); - return &context->obj.sync; + return get_event_sync( context->sync ); }
- -static int context_signaled( struct object *obj, struct wait_queue_entry *entry ) +static void context_destroy( struct object *obj ) { struct context *context = (struct context *)obj; - return context->status != STATUS_PENDING; + assert( obj->ops == &context_ops ); + release_object( context->sync ); }
- static struct context *create_thread_context( struct thread *thread ) { struct context *context; if (!(context = alloc_object( &context_ops ))) return NULL; - context->obj.sync.ops = &context_sync_ops; + context->sync = create_event_sync( 1, 0 ); context->status = STATUS_PENDING; memset( &context->regs, 0, sizeof(context->regs) ); context->regs[CTX_NATIVE].machine = native_machine; @@ -594,7 +585,7 @@ static void cleanup_thread( struct thread *thread ) if (thread->context) { thread->context->status = STATUS_ACCESS_DENIED; - wake_up( &thread->context->obj, 0 ); + set_event( thread->context->sync ); release_object( thread->context ); thread->context = NULL; } @@ -1938,7 +1929,7 @@ DECL_HANDLER(select) } ctx->status = STATUS_SUCCESS; current->suspend_cookie = req->cookie; - wake_up( &ctx->obj, 0 ); + set_event( ctx->sync ); }
if (!req->cookie) goto invalid_param;
From: Rémi Bernon rbernon@codeweavers.com
--- server/process.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-)
diff --git a/server/process.c b/server/process.c index eac2df227c9..85e50d8b63b 100644 --- a/server/process.c +++ b/server/process.c @@ -144,6 +144,7 @@ static const struct fd_ops process_fd_ops = struct startup_info { struct object obj; /* object header */ + struct event *sync; /* event object as sync */ struct process *process; /* created process */ data_size_t info_size; /* size of startup info */ data_size_t data_size; /* size of whole startup data */ @@ -152,18 +153,8 @@ struct startup_info
static void startup_info_dump( struct object *obj, int verbose ); static struct sync *startup_info_get_sync( struct object *obj ); -static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry ); static void startup_info_destroy( struct object *obj );
-static const struct sync_ops startup_info_sync_ops = -{ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - startup_info_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ -}; - static const struct object_ops startup_info_ops = { sizeof(struct startup_info), /* size */ @@ -577,7 +568,7 @@ static void set_process_startup_state( struct process *process, enum startup_sta if (process->startup_state == STARTUP_IN_PROGRESS) process->startup_state = state; if (process->startup_info) { - wake_up( &process->startup_info->obj, 0 ); + set_event( process->startup_info->sync ); release_object( process->startup_info ); process->startup_info = NULL; } @@ -905,6 +896,7 @@ static void startup_info_destroy( struct object *obj ) assert( obj->ops == &startup_info_ops ); free( info->data ); if (info->process) release_object( info->process ); + release_object( info->sync ); }
static void startup_info_dump( struct object *obj, int verbose ) @@ -923,13 +915,7 @@ static struct sync *startup_info_get_sync( struct object *obj ) { struct startup_info *info = (struct startup_info *)obj; assert( obj->ops == &startup_info_ops ); - return &info->obj.sync; -} - -static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry ) -{ - struct startup_info *info = (struct startup_info *)obj; - return info->process && info->process->startup_state != STARTUP_IN_PROGRESS; + return get_event_sync( info->sync ); }
/* get a process from an id (and increment the refcount) */ @@ -1240,7 +1226,7 @@ DECL_HANDLER(new_process) release_object( parent ); return; } - info->obj.sync.ops = &startup_info_sync_ops; + info->sync = create_event_sync( 1, 0 ); info->process = NULL; info->data = NULL;
From: Rémi Bernon rbernon@codeweavers.com
--- server/fd.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/server/fd.c b/server/fd.c index 9005c2803d2..9bcfce560d8 100644 --- a/server/fd.c +++ b/server/fd.c @@ -258,6 +258,7 @@ static const struct object_ops inode_ops = struct file_lock { struct object obj; /* object header */ + struct event *sync; /* event object as sync */ struct fd *fd; /* fd owning this lock */ struct list fd_entry; /* entry in list of locks on a given fd */ struct list inode_entry; /* entry in inode list of locks */ @@ -270,16 +271,7 @@ struct file_lock
static void file_lock_dump( struct object *obj, int verbose ); static struct sync *file_lock_get_sync( struct object *obj ); -static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry ); - -static const struct sync_ops file_lock_sync_ops = -{ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - file_lock_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ -}; +static void file_lock_destroy( struct object *obj );
static const struct object_ops file_lock_ops = { @@ -298,7 +290,7 @@ static const struct object_ops file_lock_ops = no_open_file, /* open_file */ no_kernel_obj_list, /* get_kernel_obj_list */ no_close_handle, /* close_handle */ - no_destroy /* destroy */ + file_lock_destroy /* destroy */ };
@@ -1235,14 +1227,14 @@ static struct sync *file_lock_get_sync( struct object *obj ) { struct file_lock *lock = (struct file_lock *)obj; assert( obj->ops == &file_lock_ops ); - return &lock->obj.sync; + return get_event_sync( lock->sync ); }
-static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry ) +static void file_lock_destroy( struct object *obj ) { struct file_lock *lock = (struct file_lock *)obj; - /* lock is signaled if it has lost its owner */ - return !lock->process; + assert( obj->ops == &file_lock_ops ); + release_object( lock->sync ); }
/* set (or remove) a Unix lock if possible for the given range */ @@ -1424,7 +1416,7 @@ static struct file_lock *add_lock( struct fd *fd, int shared, file_pos_t start, struct file_lock *lock;
if (!(lock = alloc_object( &file_lock_ops ))) return NULL; - lock->obj.sync.ops = &file_lock_sync_ops; + lock->sync = create_event_sync( 1, 0 ); lock->shared = shared; lock->start = start; lock->end = end; @@ -1454,7 +1446,7 @@ static void remove_lock( struct file_lock *lock, int remove_unix ) if (remove_unix) remove_unix_locks( lock->fd, lock->start, lock->end ); if (list_empty( &inode->locks )) inode_close_pending( inode, 1 ); lock->process = NULL; - wake_up( &lock->obj, 0 ); + set_event( lock->sync ); release_object( lock ); }
From: Rémi Bernon rbernon@codeweavers.com
--- server/debugger.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-)
diff --git a/server/debugger.c b/server/debugger.c index 8024556d77d..460483a1591 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -43,6 +43,7 @@ enum debug_event_state { EVENT_QUEUED, EVENT_SENT, EVENT_DELAYED, EVENT_CONTINUE struct debug_event { struct object obj; /* object header */ + struct event *sync; /* event object as sync */ struct list entry; /* entry in event queue */ struct thread *sender; /* thread which sent this event */ struct file *file; /* file object for events that need one */ @@ -76,18 +77,8 @@ struct debug_obj
static void debug_event_dump( struct object *obj, int verbose ); static struct sync *debug_event_get_sync( struct object *obj ); -static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry ); static void debug_event_destroy( struct object *obj );
-static const struct sync_ops debug_event_sync_ops = -{ - add_queue, /* add_queue */ - remove_queue, /* remove_queue */ - debug_event_signaled, /* signaled */ - no_satisfied, /* satisfied */ - no_signal, /* signal */ -}; - static const struct object_ops debug_event_ops = { sizeof(struct debug_event), /* size */ @@ -273,6 +264,7 @@ static void link_event( struct debug_obj *debug_obj, struct debug_event *event ) static void resume_event( struct debug_obj *debug_obj, struct debug_event *event ) { event->state = EVENT_QUEUED; + reset_event( event->sync ); if (!event->sender->process->debug_event) { grab_object( debug_obj ); @@ -285,6 +277,7 @@ static void resume_event( struct debug_obj *debug_obj, struct debug_event *event static void delay_event( struct debug_obj *debug_obj, struct debug_event *event ) { event->state = EVENT_DELAYED; + reset_event( event->sync ); if (event->sender->process->debug_event == event) event->sender->process->debug_event = NULL; }
@@ -315,14 +308,7 @@ static struct sync *debug_event_get_sync( struct object *obj ) { struct debug_event *debug_event = (struct debug_event *)obj; assert( obj->ops == &debug_event_ops ); - return &debug_event->obj.sync; -} - -static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry ) -{ - struct debug_event *debug_event = (struct debug_event *)obj; - assert( obj->ops == &debug_event_ops ); - return debug_event->state == EVENT_CONTINUED; + return get_event_sync( debug_event->sync ); }
static void debug_event_destroy( struct object *obj ) @@ -332,6 +318,7 @@ static void debug_event_destroy( struct object *obj )
if (event->file) release_object( event->file ); release_object( event->sender ); + release_object( event->sync ); }
static void debug_obj_dump( struct object *obj, int verbose ) @@ -433,7 +420,7 @@ static int continue_debug_event( struct debug_obj *debug_obj, struct process *pr assert( event->sender->process->debug_event == event ); event->status = status; event->state = EVENT_CONTINUED; - wake_up( &event->obj, 0 ); + set_event( event->sync ); unlink_event( debug_obj, event ); resume_process( process ); return 1; @@ -454,7 +441,7 @@ static struct debug_event *alloc_debug_event( struct thread *thread, int code, c
/* build the event */ if (!(event = alloc_object( &debug_event_ops ))) return NULL; - event->obj.sync.ops = &debug_event_sync_ops; + event->sync = create_event_sync( 1, 0 ); event->state = EVENT_QUEUED; event->sender = (struct thread *)grab_object( thread ); event->file = NULL; @@ -546,7 +533,7 @@ void debugger_detach( struct process *process, struct debug_obj *debug_obj ) assert( event->state != EVENT_CONTINUED ); event->status = DBG_CONTINUE; event->state = EVENT_CONTINUED; - wake_up( &event->obj, 0 ); + set_event( event->sync ); unlink_event( debug_obj, event ); /* from queued debug event */ resume_process( process ); @@ -592,6 +579,7 @@ DECL_HANDLER(wait_debug_event) if ((event = find_event_to_send( debug_obj ))) { event->state = EVENT_SENT; + reset_event( event->sync ); event->sender->process->debug_event = event; reply->pid = get_process_id( event->sender->process ); reply->tid = get_thread_id( event->sender );
v2: Assert that event syncs allocation succeeds as we don't handle allocation failures on the caller side, flag them as internal so they cannot be signaled with SELECT_SIGNAL_AND_WAIT (fixing the test failures).
Hmm kernel32:change failure still looks related, I'll have a look.