For https://gitlab.winehq.org/wine/wine/-/merge_requests/7226
This MR introduces a new wineserver "sync" entity, to be used by objects to implement the signal/wait operations. Later, the server sync implementations will be reduced as much as possible to event/mutex/semaphore/queue[^1]. I think it will then make the integration of ntsync cleaner, with inproc syncs being a separate flavor from the traditional server-side syncs.
Unlike how the fd struct have been implemented, I chose not to derive these syncs from the object base, because it seemed inconvenient to have to declare all the unused ops. Still they are refcounted, to allow us to share a sync between multiple objects, which will later benefit the console objects use cases, maybe others.
This makes me thing that the fd struct could also benefit from being lightweight entities as well, as it doesn't seem they really use most of the object vtable ops, and arguably we could have a common "light" refcounted/dumpable base for all fds, syncs and objects, but I didn't want to jump into that rabbit hole and it could be implemented later.
[^1]: And server-only async/completion waits, which maybe can be changed to use events too, but I'm not familiar enough.
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 27a40ce38ad..bff5c50ad5a 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 */ @@ -387,6 +399,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; @@ -456,6 +469,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; @@ -681,6 +695,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; @@ -974,18 +989,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; @@ -1015,7 +1030,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() ); @@ -1069,13 +1084,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; @@ -1191,7 +1206,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 | 51 ++++++++++++++++++++++++++++++---------- 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 | 57 +++++++++++++++++++++++++++++++++++++++------ server/timer.c | 9 +++++++ server/token.c | 1 + server/window.c | 1 + server/winstation.c | 2 ++ 35 files changed, 325 insertions(+), 35 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..f7109d2d470 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 */ + default_fd_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..497056d9fa4 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,8 +2188,7 @@ 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 = get_obj_fd( obj ); int ret = fd->signaled; @@ -2178,6 +2196,15 @@ static int default_fd_signaled( struct object *obj, struct wait_queue_entry *ent return ret; }
+/* 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; + release_object( fd ); + return sync; +} + int default_fd_get_poll_events( struct fd *fd ) { int events = 0; 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..854d7a50378 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 */ + no_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 bff5c50ad5a..770c50784f7 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 */ @@ -457,6 +463,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 ) { @@ -645,6 +658,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; @@ -667,6 +687,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; @@ -989,18 +1016,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->ops->satisfied( entry->obj, 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->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->sync.ops->remove_queue( entry->obj, entry ); + { + struct sync *sync = entry->obj->ops->get_sync( entry->obj ); + sync->ops->remove_queue( entry->obj, entry ); + } if (wait->user) remove_timeout_user( wait->user ); free( wait ); return status; @@ -1029,8 +1064,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->ops->add_queue( obj, entry )) { wait->count = i; end_wait( current, get_error() ); @@ -1084,13 +1120,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->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->sync.ops->signaled( entry->obj, entry )) return i; + { + struct sync *sync = entry->obj->ops->get_sync( entry->obj ); + if (sync->ops->signaled( entry->obj, entry )) return i; + } }
if ((wait->flags & SELECT_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC; @@ -1206,7 +1248,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->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 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/async.c | 8 ++++-- server/completion.c | 17 +++++++++--- server/console.c | 40 +++++++++++++++++++------- server/debugger.c | 17 +++++++++--- server/device.c | 9 ++++-- server/event.c | 38 ++++++++++++++++++++----- server/fd.c | 29 ++++++++++++++----- server/file.h | 2 +- server/mutex.c | 17 ++++++++---- server/object.c | 68 ++++++++++++++++++++++++++++++++++++++++++--- server/object.h | 14 ++++++++-- server/process.c | 24 ++++++++++++---- server/process.h | 1 + server/queue.c | 22 ++++++++++----- server/semaphore.c | 17 ++++++++++-- server/thread.c | 47 ++++++++++++++++++------------- server/thread.h | 1 + server/timer.c | 8 ++++-- 18 files changed, 294 insertions(+), 85 deletions(-)
diff --git a/server/async.c b/server/async.c index 50c4bcf58c2..399fb530789 100644 --- a/server/async.c +++ b/server/async.c @@ -37,6 +37,7 @@ struct async { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct thread *thread; /* owning thread */ struct list queue_entry; /* entry in async queue list */ struct list process_entry; /* entry in process list */ @@ -73,6 +74,8 @@ static void async_destroy( struct object *obj );
static const struct sync_ops async_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ async_signaled, /* signaled */ @@ -116,7 +119,7 @@ static struct sync *async_get_sync( struct object *obj ) { struct async *async = (struct async *)obj; assert( obj->ops == &async_ops ); - return &async->obj.sync; + return async->sync; }
static int async_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -172,6 +175,7 @@ static void async_destroy( struct object *obj ) if (async->event) release_object( async->event ); if (async->iosb) release_object( async->iosb ); release_object( async->thread ); + release_sync( async->sync ); }
/* notifies client thread of new status of its async request */ @@ -274,7 +278,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->sync = alloc_sync( &async_sync_ops ); async->thread = (struct thread *)grab_object( thread ); async->event = event; async->data = *data; diff --git a/server/completion.c b/server/completion.c index 052112866a4..cf3588c4267 100644 --- a/server/completion.c +++ b/server/completion.c @@ -63,6 +63,7 @@ struct comp_msg struct completion_wait { struct object obj; + struct sync *sync; obj_handle_t handle; struct completion *completion; struct thread *thread; @@ -73,6 +74,7 @@ struct completion_wait struct completion { struct object obj; + struct sync *sync; struct list queue; struct list wait_queue; unsigned int depth; @@ -87,6 +89,8 @@ static void completion_wait_destroy( struct object * );
static const struct sync_ops completion_wait_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ completion_wait_signaled, /* signaled */ @@ -118,6 +122,7 @@ static void completion_wait_destroy( struct object *obj ) { struct completion_wait *wait = (struct completion_wait *)obj; free( wait->msg ); + release_sync( wait->sync ); }
static void completion_wait_dump( struct object *obj, int verbose ) @@ -132,7 +137,7 @@ 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; + return wait->sync; }
static int completion_wait_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -173,6 +178,8 @@ static void completion_destroy( struct object * );
static const struct sync_ops completion_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ completion_signaled, /* signaled */ @@ -209,6 +216,8 @@ static void completion_destroy( struct object *obj) { free( tmp ); } + + release_sync( completion->sync ); }
static void completion_dump( struct object *obj, int verbose ) @@ -223,7 +232,7 @@ static struct sync *completion_get_sync( struct object *obj ) { struct completion *completion = (struct completion *)obj; assert( obj->ops == &completion_ops ); - return &completion->obj.sync; + return completion->sync; }
static int completion_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -275,7 +284,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->sync = alloc_sync( &completion_wait_sync_ops ); wait->completion = NULL; wait->thread = thread; wait->msg = NULL; @@ -297,7 +306,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; + completion->sync = alloc_sync( &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 8ee1690551b..9b0e7e2e63a 100644 --- a/server/console.c +++ b/server/console.c @@ -53,6 +53,7 @@ struct history_line struct console { struct object obj; /* object header */ + struct sync *sync; /* object sync */ int signaled; /* is console signaled */ struct thread *renderer; /* console renderer thread */ struct screen_buffer *active; /* active screen buffer */ @@ -79,6 +80,8 @@ static int console_add_queue( struct object *obj, struct wait_queue_entry *entry
static const struct sync_ops console_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ console_add_queue, /* add_queue */ remove_queue, /* remove_queue */ console_signaled, /* signaled */ @@ -140,6 +143,7 @@ struct console_host_ioctl struct console_server { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct fd *fd; /* pseudo-fd for ioctls */ struct console *console; /* attached console */ struct list queue; /* ioctl queue */ @@ -162,6 +166,8 @@ static struct object *console_server_open_file( struct object *obj, unsigned int
static const struct sync_ops console_server_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ console_server_signaled, /* signaled */ @@ -220,6 +226,7 @@ struct font_info struct screen_buffer { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct list entry; /* entry in list of all screen buffers */ struct console *input; /* associated console input */ unsigned int id; /* buffer id */ @@ -237,6 +244,8 @@ static struct object *screen_buffer_open_file( struct object *obj, unsigned int
static const struct sync_ops screen_buffer_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ screen_buffer_signaled, /* signaled */ @@ -312,6 +321,7 @@ static const struct object_ops console_device_ops = struct console_input { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct fd *fd; /* pseudo-fd */ struct list entry; /* entry in console->inputs */ struct console *console; /* associated console at creation time */ @@ -327,6 +337,8 @@ static void console_input_destroy( struct object *obj );
static const struct sync_ops console_input_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ console_input_signaled, /* signaled */ @@ -377,6 +389,7 @@ static const struct fd_ops console_input_fd_ops = struct console_output { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct fd *fd; /* pseudo-fd */ struct list entry; /* entry in console->outputs */ struct console *console; /* associated console at creation time */ @@ -392,6 +405,8 @@ static void console_output_destroy( struct object *obj );
static const struct sync_ops console_output_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ console_output_signaled, /* signaled */ @@ -525,7 +540,7 @@ static struct sync *console_get_sync( struct object *obj ) { struct console *console = (struct console *)obj; assert( obj->ops == &console_ops ); - return &console->obj.sync; + return console->sync; }
static enum server_fd_type console_get_fd_type( struct fd *fd ) @@ -565,7 +580,7 @@ static struct object *create_console(void) struct console *console;
if (!(console = alloc_object( &console_ops ))) return NULL; - console->obj.sync.ops = &console_sync_ops; + console->sync = alloc_sync( &console_sync_ops ); console->renderer = NULL; console->signaled = 0; console->active = NULL; @@ -670,7 +685,7 @@ static struct object *create_screen_buffer( struct console *console ) }
if (!(screen_buffer = alloc_object( &screen_buffer_ops ))) return NULL; - screen_buffer->obj.sync.ops = &screen_buffer_sync_ops; + screen_buffer->sync = alloc_sync( &screen_buffer_sync_ops ); screen_buffer->id = ++console->last_id; screen_buffer->input = console; init_async_queue( &screen_buffer->ioctl_q ); @@ -805,6 +820,7 @@ static void console_destroy( struct object *obj ) free_async_queue( &console->read_q ); if (console->fd) release_object( console->fd ); + release_sync( console->sync ); }
static struct object *create_console_connection( struct console *console ) @@ -881,6 +897,7 @@ static void screen_buffer_destroy( struct object *obj ) } if (screen_buffer->fd) release_object( screen_buffer->fd ); free_async_queue( &screen_buffer->ioctl_q ); + release_sync( screen_buffer->sync ); }
static int screen_buffer_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -911,7 +928,7 @@ 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; + return screen_buffer->sync; }
static void console_server_dump( struct object *obj, int verbose ) @@ -926,6 +943,7 @@ static void console_server_destroy( struct object *obj ) assert( obj->ops == &console_server_ops ); disconnect_console_server( server ); if (server->fd) release_object( server->fd ); + release_sync( server->sync ); }
static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name, @@ -984,7 +1002,7 @@ 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; + return server->sync; }
static struct object *console_server_open_file( struct object *obj, unsigned int access, @@ -998,7 +1016,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->sync = alloc_sync( &console_server_sync_ops ); server->console = NULL; server->busy = 0; server->once_input = 0; @@ -1379,7 +1397,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->sync = alloc_sync( &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) @@ -1404,7 +1422,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->sync = alloc_sync( &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) @@ -1486,7 +1504,7 @@ 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; + return console_input->sync; }
static struct object *console_input_open_file( struct object *obj, unsigned int access, @@ -1502,6 +1520,7 @@ static void console_input_destroy( struct object *obj ) assert( obj->ops == &console_input_ops ); if (console_input->fd) release_object( console_input->fd ); if (console_input->console) list_remove( &console_input->entry ); + release_sync( console_input->sync ); }
static void console_input_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) @@ -1564,7 +1583,7 @@ 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; + return console_output->sync; }
static struct object *console_output_open_file( struct object *obj, unsigned int access, @@ -1580,6 +1599,7 @@ static void console_output_destroy( struct object *obj ) assert( obj->ops == &console_output_ops ); if (console_output->fd) release_object( console_output->fd ); if (console_output->console) list_remove( &console_output->entry ); + release_sync( console_output->sync ); }
static void console_output_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) diff --git a/server/debugger.c b/server/debugger.c index 8024556d77d..576a751823d 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 sync *sync; /* object 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 */ @@ -69,6 +70,7 @@ struct type_descr debug_obj_type = struct debug_obj { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct list event_queue; /* pending events queue */ unsigned int flags; /* debug flags */ }; @@ -81,6 +83,8 @@ static void debug_event_destroy( struct object *obj );
static const struct sync_ops debug_event_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ debug_event_signaled, /* signaled */ @@ -115,6 +119,8 @@ static void debug_obj_destroy( struct object *obj );
static const struct sync_ops debug_obj_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ debug_obj_signaled, /* signaled */ @@ -315,7 +321,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; + return debug_event->sync; }
static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -332,6 +338,7 @@ static void debug_event_destroy( struct object *obj )
if (event->file) release_object( event->file ); release_object( event->sender ); + release_sync( event->sync ); }
static void debug_obj_dump( struct object *obj, int verbose ) @@ -346,7 +353,7 @@ 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; + return debug_obj->sync; }
static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -368,6 +375,8 @@ static void debug_obj_destroy( struct object *obj ) /* free all pending events */ while ((ptr = list_head( &debug_obj->event_queue ))) unlink_event( debug_obj, LIST_ENTRY( ptr, struct debug_event, entry )); + + release_sync( debug_obj->sync ); }
struct debug_obj *get_debug_obj( struct process *process, obj_handle_t handle, unsigned int access ) @@ -385,7 +394,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->sync = alloc_sync( &debug_obj_sync_ops ); debug_obj->flags = flags; list_init( &debug_obj->event_queue ); } @@ -454,7 +463,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 = alloc_sync( &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 f7109d2d470..62dd7b70d07 100644 --- a/server/device.c +++ b/server/device.c @@ -84,6 +84,7 @@ static const struct object_ops irp_call_ops = struct device_manager { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct list devices; /* list of devices */ struct list requests; /* list of pending irps across all devices */ struct irp_call *current_call; /* call currently executed on client side */ @@ -97,6 +98,8 @@ static void device_manager_destroy( struct object *obj );
static const struct sync_ops device_manager_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ device_manager_signaled, /* signaled */ @@ -773,7 +776,7 @@ 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; + return manager->sync; }
static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -817,6 +820,8 @@ static void device_manager_destroy( struct object *obj ) assert( !irp->file && !irp->async ); release_object( irp ); } + + release_sync( manager->sync ); }
static struct device_manager *create_device_manager(void) @@ -825,7 +830,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->sync = alloc_sync( &device_manager_sync_ops ); manager->current_call = NULL; list_init( &manager->devices ); list_init( &manager->requests ); diff --git a/server/event.c b/server/event.c index eeba7fcaf58..85c9686f2c9 100644 --- a/server/event.c +++ b/server/event.c @@ -53,6 +53,7 @@ struct type_descr event_type = struct event { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct list kernel_object; /* list of kernel object pointers */ int manual_reset; /* is it a manual reset event? */ int signaled; /* event has been signaled */ @@ -60,6 +61,7 @@ struct event
static void event_dump( struct object *obj, int verbose ); static struct sync *event_get_sync( struct object *obj ); +static void event_destroy( 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); @@ -67,6 +69,8 @@ static struct list *event_get_kernel_obj_list( struct object *obj );
static const struct sync_ops event_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ event_signaled, /* signaled */ @@ -91,7 +95,7 @@ static const struct object_ops event_ops = no_open_file, /* open_file */ event_get_kernel_obj_list, /* get_kernel_obj_list */ no_close_handle, /* close_handle */ - no_destroy /* destroy */ + event_destroy, /* destroy */ };
@@ -112,14 +116,18 @@ struct type_descr keyed_event_type = struct keyed_event { struct object obj; /* object header */ + struct sync *sync; /* object sync */ };
static void keyed_event_dump( struct object *obj, int verbose ); static struct sync *keyed_event_get_sync( struct object *obj ); +static void keyed_event_destroy( 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 = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ keyed_event_signaled, /* signaled */ @@ -144,7 +152,7 @@ static const struct object_ops keyed_event_ops = no_open_file, /* open_file */ no_kernel_obj_list, /* get_kernel_obj_list */ no_close_handle, /* close_handle */ - no_destroy /* destroy */ + keyed_event_destroy, /* destroy */ };
@@ -159,7 +167,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; + event->sync = alloc_sync( &event_sync_ops ); list_init( &event->kernel_object ); event->manual_reset = manual_reset; event->signaled = initial_state; @@ -205,7 +213,14 @@ static struct sync *event_get_sync( struct object *obj ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); - return &event->obj.sync; + return event->sync; +} + +static void event_destroy( struct object *obj ) +{ + struct event *event = (struct event *)obj; + assert( obj->ops == &event_ops ); + release_sync( event->sync ); }
static int event_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -253,7 +268,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; + event->sync = alloc_sync( &keyed_event_sync_ops ); } } return event; @@ -273,7 +288,14 @@ 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; + return event->sync; +} + +static void keyed_event_destroy( struct object *obj ) +{ + struct event *event = (struct event *)obj; + assert( obj->ops == &keyed_event_ops ); + release_sync( event->sync ); }
static enum select_opcode matching_op( enum select_opcode op ) @@ -283,6 +305,8 @@ static enum select_opcode matching_op( enum select_opcode op )
static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *entry ) { + struct keyed_event *event = (struct keyed_event *)obj; + struct sync *sync = event->sync; struct wait_queue_entry *ptr; struct process *process; enum select_opcode select_op; @@ -293,7 +317,7 @@ static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *en select_op = get_wait_queue_select_op( entry ); if (select_op != SELECT_KEYED_EVENT_WAIT && select_op != SELECT_KEYED_EVENT_RELEASE) return 1;
- LIST_FOR_EACH_ENTRY( ptr, &obj->wait_queue, struct wait_queue_entry, entry ) + LIST_FOR_EACH_ENTRY( ptr, &sync->wait_queue, struct wait_queue_entry, entry ) { if (ptr == entry) continue; if (get_wait_queue_thread( ptr )->process != process) continue; diff --git a/server/fd.c b/server/fd.c index 497056d9fa4..aa16f097f40 100644 --- a/server/fd.c +++ b/server/fd.c @@ -128,6 +128,7 @@ struct closed_fd struct fd { struct object obj; /* object header */ + struct sync *sync; /* object 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 */ @@ -163,6 +164,8 @@ static void fd_destroy( struct object *obj );
const struct sync_ops fd_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ fd_signaled, /* signaled */ @@ -268,6 +271,7 @@ static const struct object_ops inode_ops = struct file_lock { struct object obj; /* object header */ + struct sync *sync; /* object 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 */ @@ -280,10 +284,13 @@ struct file_lock
static void file_lock_dump( struct object *obj, int verbose ); static struct sync *file_lock_get_sync( struct object *obj ); +static void file_lock_destroy( 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 = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ file_lock_signaled, /* signaled */ @@ -308,7 +315,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 */ };
@@ -1245,7 +1252,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 lock->sync; +} + +static void file_lock_destroy( struct object *obj ) +{ + struct file_lock *lock = (struct file_lock *)obj; + assert( obj->ops == &file_lock_ops ); + release_sync( lock->sync ); }
static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -1434,7 +1448,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 = alloc_sync( &file_lock_sync_ops ); lock->shared = shared; lock->start = start; lock->end = end; @@ -1576,7 +1590,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 fd->sync; }
static void fd_destroy( struct object *obj ) @@ -1603,6 +1617,7 @@ static void fd_destroy( struct object *obj ) if (fd->unix_fd != -1) close( fd->unix_fd ); free( fd->unix_name ); } + release_sync( fd->sync ); }
/* check if the desired access is possible without violating */ @@ -1701,7 +1716,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 = alloc_sync( &fd_sync_ops ); fd->fd_ops = NULL; fd->user = NULL; fd->inode = NULL; @@ -1741,7 +1756,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 = alloc_sync( &fd_sync_ops ); fd->fd_ops = fd_user_ops; fd->user = user; fd->inode = NULL; @@ -2200,7 +2215,7 @@ static int fd_signaled( struct object *obj, struct wait_queue_entry *entry ) 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 = fd->sync; release_object( fd ); return sync; } diff --git a/server/file.h b/server/file.h index 06622c40783..0b8c87757b7 100644 --- a/server/file.h +++ b/server/file.h @@ -24,7 +24,6 @@ #include <sys/types.h>
#include "object.h" -#include "thread.h"
struct fd; struct mapping; @@ -120,6 +119,7 @@ extern void no_fd_read( struct fd *fd, struct async *async, file_pos_t pos ); extern void no_fd_write( struct fd *fd, struct async *async, file_pos_t pos ); extern void no_fd_flush( struct fd *fd, struct async *async ); extern void no_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class ); +extern struct sync *default_fd_get_sync( struct object *obj ); extern void default_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class ); extern void no_fd_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class ); extern void no_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ); diff --git a/server/mutex.c b/server/mutex.c index f2ddbe9cc1e..493f7f60ad7 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -53,6 +53,7 @@ struct type_descr mutex_type = struct mutex { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct thread *owner; /* mutex owner */ unsigned int count; /* recursion count */ int abandoned; /* has it been abandoned? */ @@ -68,6 +69,8 @@ static int mutex_signal( struct object *obj, unsigned int access );
static const struct sync_ops mutex_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ mutex_signaled, /* signaled */ @@ -129,7 +132,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->sync = alloc_sync( &mutex_sync_ops ); mutex->count = 0; mutex->owner = NULL; mutex->abandoned = 0; @@ -164,7 +167,7 @@ static struct sync *mutex_get_sync( struct object *obj ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); - return &mutex->obj.sync; + return mutex->sync; }
static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -208,9 +211,13 @@ static void mutex_destroy( struct object *obj ) struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops );
- if (!mutex->count) return; - mutex->count = 0; - do_release( mutex ); + if (mutex->count) + { + mutex->count = 0; + do_release( mutex ); + } + + release_sync( mutex->sync ); }
/* create a mutex */ diff --git a/server/object.c b/server/object.c index 302bbb53523..eead499e2c4 100644 --- a/server/object.c +++ b/server/object.c @@ -287,8 +287,15 @@ WCHAR *default_get_full_name( struct object *obj, data_size_t *ret_len ) return (WCHAR *)ret; }
+static void no_sync_destroy( struct sync *sync ) +{ + assert( 0 ); +} + static const struct sync_ops no_sync_ops = { + 0, /* size */ + no_sync_destroy, /* destroy */ no_add_queue, /* add_queue */ NULL, /* remove_queue */ NULL, /* signaled */ @@ -298,6 +305,7 @@ static const struct sync_ops no_sync_ops =
static struct sync no_sync = { + 1, &no_sync_ops, };
@@ -311,10 +319,8 @@ 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 ); #ifdef DEBUG_OBJECTS list_add_head( &object_list, &obj->obj_list ); #endif @@ -325,6 +331,16 @@ void *alloc_object( const struct object_ops *ops ) return NULL; }
+struct sync *alloc_sync( const struct sync_ops *ops ) +{ + struct sync *sync = mem_alloc( ops->size ); + assert( sync ); + sync->refcount = 1; + sync->ops = ops; + list_init( &sync->wait_queue ); + return sync; +} + /* free an object once it has been destroyed */ static void free_object( struct object *obj ) { @@ -553,8 +569,6 @@ void release_object( void *ptr ) if (!--obj->refcount) { assert( !obj->handle_count ); - /* if the refcount is 0, nobody can be in the wait queue */ - assert( list_empty( &obj->wait_queue )); free_kernel_objects( obj ); unlink_named_object( obj ); obj->ops->destroy( obj ); @@ -562,6 +576,27 @@ void release_object( void *ptr ) } }
+/* grab a sync (i.e. increment its refcount) and return the sync */ +struct sync *grab_sync( void *ptr ) +{ + struct sync *sync = (struct sync *)ptr; + assert( sync->refcount < INT_MAX ); + sync->refcount++; + return sync; +} + +/* release a sync (i.e. decrement its refcount) */ +void release_sync( void *ptr ) +{ + struct sync *sync = (struct sync *)ptr; + assert( sync->refcount ); + if (!--sync->refcount) + { + sync->ops->destroy( sync ); + free( sync ); + } +} + /* find an object by its name; the refcount is incremented */ struct object *find_object( const struct namespace *namespace, const struct unicode_str *name, unsigned int attributes ) @@ -640,6 +675,13 @@ int no_signal( struct object *obj, unsigned int access ) return 0; }
+void sync_destroy( struct sync *obj ) +{ + struct sync *sync = (struct sync *)obj; + /* if the refcount is 0, nobody can be in the wait queue */ + assert( list_empty( &sync->wait_queue ) ); +} + struct fd *no_get_fd( struct object *obj ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); @@ -651,6 +693,24 @@ struct sync *no_get_sync( struct object *obj ) return &no_sync; }
+/* attempt to wake threads sleeping on the object wait queue */ +void sync_wake_up( struct sync *sync, int max ) +{ + struct list *ptr; + int ret; + + if (sync == &no_sync) return; + + LIST_FOR_EACH( ptr, &sync->wait_queue ) + { + struct wait_queue_entry *entry = LIST_ENTRY( ptr, struct wait_queue_entry, entry ); + if (!(ret = wake_thread( get_wait_queue_thread( entry )))) continue; + if (ret > 0 && max && !--max) break; + /* restart at the head of the list since a wake up can change the object wait queue */ + ptr = &sync->wait_queue; + } +} + 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 3db4f3d56cb..08ee577a91a 100644 --- a/server/object.h +++ b/server/object.h @@ -42,6 +42,7 @@ struct async; struct async_queue; struct winstation; struct object_type; +struct sync;
struct unicode_str @@ -66,6 +67,10 @@ struct type_descr /* operations valid on waitable objects */ struct sync_ops { + /* size of this sync type */ + size_t size; + /* destroy a sync object */ + void (*destroy)(struct sync *); /* 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 */ @@ -80,7 +85,9 @@ struct sync_ops
struct sync { + unsigned int refcount; const struct sync_ops *ops; + struct list wait_queue; };
/* operations valid on all objects */ @@ -126,8 +133,6 @@ 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; unsigned int is_permanent:1; @@ -157,6 +162,7 @@ extern void mark_block_uninitialized( void *ptr, size_t size ); extern void *mem_alloc( size_t size ) __WINE_ALLOC_SIZE(1) __WINE_DEALLOC(free) __WINE_MALLOC; extern void *memdup( const void *data, size_t len ) __WINE_ALLOC_SIZE(2) __WINE_DEALLOC(free); extern void *alloc_object( const struct object_ops *ops ); +extern struct sync *alloc_sync( const struct sync_ops *ops ); extern void namespace_add( struct namespace *namespace, struct object_name *ptr ); extern const WCHAR *get_object_name( struct object *obj, data_size_t *len ); extern WCHAR *default_get_full_name( struct object *obj, data_size_t *ret_len ) __WINE_DEALLOC(free) __WINE_MALLOC; @@ -176,14 +182,18 @@ extern void free_kernel_objects( struct object *obj ); /* that the thing pointed to starts with a struct object... */ extern struct object *grab_object( void *obj ); extern void release_object( void *obj ); +extern struct sync *grab_sync( void *obj ); +extern void release_sync( void *obj ); extern struct object *find_object( const struct namespace *namespace, const struct unicode_str *name, unsigned int attributes ); extern struct object *find_object_index( const struct namespace *namespace, unsigned int index ); extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern void no_satisfied( struct object *obj, struct wait_queue_entry *entry ); extern int no_signal( struct object *obj, unsigned int access ); +extern void sync_destroy( struct sync *obj ); extern struct fd *no_get_fd( struct object *obj ); extern struct sync *no_get_sync( struct object *obj ); +extern void sync_wake_up( struct sync *sync, int max ); 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 eac2df227c9..0201f92c44a 100644 --- a/server/process.c +++ b/server/process.c @@ -100,6 +100,8 @@ static void terminate_process( struct process *process, struct thread *skip, int
static const struct sync_ops process_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ process_signaled, /* signaled */ @@ -144,6 +146,7 @@ static const struct fd_ops process_fd_ops = struct startup_info { struct object obj; /* object header */ + struct sync *sync; /* object 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 */ @@ -157,6 +160,8 @@ static void startup_info_destroy( struct object *obj );
static const struct sync_ops startup_info_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ startup_info_signaled, /* signaled */ @@ -209,6 +214,7 @@ static void job_destroy( struct object *obj ); struct job { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct list process_list; /* list of processes */ int num_processes; /* count of running processes */ int total_processes; /* count of processes which have been assigned */ @@ -224,6 +230,8 @@ struct job
static const struct sync_ops job_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ job_signaled, /* signaled */ @@ -261,7 +269,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; + job->sync = alloc_sync( &job_sync_ops ); list_init( &job->process_list ); list_init( &job->child_job_list ); job->num_processes = 0; @@ -458,6 +466,8 @@ static void job_destroy( struct object *obj ) list_remove( &job->parent_job_entry ); release_object( job->parent ); } + + release_sync( job->sync ); }
static void job_dump( struct object *obj, int verbose ) @@ -472,7 +482,7 @@ static struct sync *job_get_sync( struct object *obj ) { struct job *job = (struct job *)obj; assert( obj->ops == &job_ops ); - return &job->obj.sync; + return job->sync; }
static int job_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -676,7 +686,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->sync = alloc_sync( &process_sync_ops ); process->parent_id = 0; process->debug_obj = NULL; process->debug_event = NULL; @@ -811,6 +821,7 @@ static void process_destroy( struct object *obj ) free( process->rawinput_devices ); free( process->dir_cache ); free( process->image ); + release_sync( process->sync ); }
/* dump a process on stdout for debugging purposes */ @@ -826,7 +837,7 @@ static struct sync *process_get_sync( struct object *obj ) { struct process *process = (struct process *)obj; assert( obj->ops == &process_ops ); - return &process->obj.sync; + return process->sync; }
static int process_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -905,6 +916,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_sync( info->sync ); }
static void startup_info_dump( struct object *obj, int verbose ) @@ -923,7 +935,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; + return info->sync; }
static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -1240,7 +1252,7 @@ DECL_HANDLER(new_process) release_object( parent ); return; } - info->obj.sync.ops = &startup_info_sync_ops; + info->sync = alloc_sync( &startup_info_sync_ops ); info->process = NULL; info->data = NULL;
diff --git a/server/process.h b/server/process.h index e49529b06fa..09de931cf61 100644 --- a/server/process.h +++ b/server/process.h @@ -36,6 +36,7 @@ enum startup_state { STARTUP_IN_PROGRESS, STARTUP_DONE, STARTUP_ABORTED }; struct process { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct list entry; /* entry in system-wide process list */ process_id_t parent_id; /* parent process id (at the time of creation) */ struct list thread_list; /* thread list */ diff --git a/server/queue.c b/server/queue.c index f607fafa882..d833fac033a 100644 --- a/server/queue.c +++ b/server/queue.c @@ -115,6 +115,7 @@ struct thread_input struct msg_queue { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct fd *fd; /* optional file descriptor to poll */ int paint_count; /* pending paint messages count */ int hotkey_count; /* pending hotkey messages count */ @@ -160,6 +161,8 @@ static void timer_callback( void *private );
static const struct sync_ops msg_queue_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ msg_queue_add_queue, /* add_queue */ msg_queue_remove_queue, /* remove_queue */ msg_queue_signaled, /* signaled */ @@ -303,7 +306,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->sync = alloc_sync( &msg_queue_sync_ops ); queue->fd = NULL; queue->paint_count = 0; queue->hotkey_count = 0; @@ -1261,12 +1264,13 @@ static void cleanup_results( struct msg_queue *queue ) /* check if the thread owning the queue is hung (not checking for messages) */ static int is_queue_hung( struct msg_queue *queue ) { + struct sync *sync = queue->sync; struct wait_queue_entry *entry;
if (current_time - queue->last_get_msg <= 5 * TICKS_PER_SEC) return 0; /* less than 5 seconds since last get message -> not hung */
- LIST_FOR_EACH_ENTRY( entry, &queue->obj.wait_queue, struct wait_queue_entry, entry ) + LIST_FOR_EACH_ENTRY( entry, &sync->wait_queue, struct wait_queue_entry, entry ) { if (get_wait_queue_thread(entry)->queue == queue) return 0; /* thread is waiting on queue -> not hung */ @@ -1277,6 +1281,7 @@ static int is_queue_hung( struct msg_queue *queue ) static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; + struct sync *sync = queue->sync;
/* a thread can only wait on its own queue */ if (get_wait_queue_thread(entry)->queue != queue) @@ -1285,18 +1290,19 @@ static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *ent return 0; }
- if (queue->fd && list_empty( &obj->wait_queue )) /* first on the queue */ + if (queue->fd && list_empty( &sync->wait_queue )) /* first on the queue */ set_fd_events( queue->fd, POLLIN ); add_queue( obj, entry ); return 1; }
-static void msg_queue_remove_queue(struct object *obj, struct wait_queue_entry *entry ) +static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; + struct sync *sync = queue->sync;
remove_queue( obj, entry ); - if (queue->fd && list_empty( &obj->wait_queue )) /* last on the queue is gone */ + if (queue->fd && list_empty( &sync->wait_queue )) /* last on the queue is gone */ set_fd_events( queue->fd, 0 ); }
@@ -1312,12 +1318,13 @@ 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; + return queue->sync; }
static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; + struct sync *sync = queue->sync; int ret = 0;
if (queue->fd) @@ -1325,7 +1332,7 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr if ((ret = check_fd_events( queue->fd, POLLIN ))) /* stop waiting on select() if we are signaled */ set_fd_events( queue->fd, 0 ); - else if (!list_empty( &obj->wait_queue )) + else if (!list_empty( &sync->wait_queue )) /* restart waiting on poll() if we are no longer signaled */ set_fd_events( queue->fd, POLLIN ); } @@ -1388,6 +1395,7 @@ static void msg_queue_destroy( struct object *obj ) if (queue->hooks) release_object( queue->hooks ); if (queue->fd) release_object( queue->fd ); if (queue->shared) free_shared_object( queue->shared ); + release_sync( queue->sync ); }
static void msg_queue_poll_event( struct fd *fd, int event ) diff --git a/server/semaphore.c b/server/semaphore.c index 3ac9ff23a2d..716baf87369 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -53,18 +53,22 @@ struct type_descr semaphore_type = struct semaphore { struct object obj; /* object header */ + struct sync *sync; /* object sync */ unsigned int count; /* current count */ unsigned int max; /* maximum possible count */ };
static void semaphore_dump( struct object *obj, int verbose ); static struct sync *semaphore_get_sync( struct object *obj ); +static void semaphore_destroy( 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 );
static const struct sync_ops semaphore_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ semaphore_signaled, /* signaled */ @@ -89,7 +93,7 @@ static const struct object_ops semaphore_ops = no_open_file, /* open_file */ no_kernel_obj_list, /* get_kernel_obj_list */ no_close_handle, /* close_handle */ - no_destroy /* destroy */ + semaphore_destroy, /* destroy */ };
@@ -109,7 +113,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->sync = alloc_sync( &semaphore_sync_ops ); sem->count = initial; sem->max = max; } @@ -150,7 +154,14 @@ static struct sync *semaphore_get_sync( struct object *obj ) { struct semaphore *semaphore = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); - return &semaphore->obj.sync; + return semaphore->sync; +} + +static void semaphore_destroy( struct object *obj ) +{ + struct semaphore *semaphore = (struct semaphore *)obj; + assert( obj->ops == &semaphore_ops ); + release_sync( semaphore->sync ); }
static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry ) diff --git a/server/thread.c b/server/thread.c index 770c50784f7..43e09728f01 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 sync *sync; /* object sync */ struct list entry; /* queue linked list */ struct thread *caller; /* thread that queued this apc */ struct object *owner; /* object that queued this apc */ @@ -101,6 +102,8 @@ static void clear_apc_queue( struct list *queue );
static const struct sync_ops thread_apc_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ thread_apc_signaled, /* signaled */ @@ -134,6 +137,7 @@ static const struct object_ops thread_apc_ops = struct context { struct object obj; /* object header */ + struct sync *sync; /* object sync */ unsigned int status; /* status of the context */ struct context_data regs[2];/* context data */ }; @@ -145,10 +149,13 @@ 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 void context_destroy( struct object *obj ); static int context_signaled( struct object *obj, struct wait_queue_entry *entry );
static const struct sync_ops context_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ context_signaled, /* signaled */ @@ -173,7 +180,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 */ };
@@ -204,6 +211,8 @@ static void destroy_thread( struct object *obj );
static const struct sync_ops thread_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ thread_signaled, /* signaled */ @@ -405,7 +414,7 @@ static inline void init_thread_structure( struct thread *thread ) { int i;
- thread->obj.sync.ops = &thread_sync_ops; + thread->sync = alloc_sync( &thread_sync_ops ); thread->unix_pid = -1; /* not known yet */ thread->unix_tid = -1; /* not known yet */ thread->context = NULL; @@ -467,9 +476,15 @@ 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 context->sync; }
+static void context_destroy( struct object *obj ) +{ + struct context *context = (struct context *)obj; + assert( obj->ops == &context_ops ); + release_sync( context->sync ); +}
static int context_signaled( struct object *obj, struct wait_queue_entry *entry ) { @@ -482,7 +497,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->sync = alloc_sync( &context_sync_ops ); context->status = STATUS_PENDING; memset( &context->regs, 0, sizeof(context->regs) ); context->regs[CTX_NATIVE].machine = native_machine; @@ -646,6 +661,7 @@ static void destroy_thread( struct object *obj ) release_object( thread->process ); if (thread->id) free_ptid( thread->id ); if (thread->token) release_object( thread->token ); + release_sync( thread->sync ); }
/* dump a thread on stdout for debugging purposes */ @@ -662,7 +678,7 @@ static struct sync *thread_get_sync( struct object *obj ) { struct thread *thread = (struct thread *)obj; assert( obj->ops == &thread_ops ); - return &thread->obj.sync; + return thread->sync; }
static int thread_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -691,7 +707,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; + return apc->sync; }
static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -713,6 +729,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_sync( apc->sync ); }
/* queue an async procedure call */ @@ -722,7 +739,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 = alloc_sync( &thread_apc_sync_ops ); if (call_data) apc->call = *call_data; else apc->call.type = APC_NONE; apc->caller = NULL; @@ -962,9 +979,10 @@ int resume_thread( struct thread *thread ) /* add a thread to an object wait queue; return 1 if OK, 0 on error */ int add_queue( struct object *obj, struct wait_queue_entry *entry ) { + struct sync *sync = obj->ops->get_sync( obj ); grab_object( obj ); entry->obj = obj; - list_add_tail( &obj->wait_queue, &entry->entry ); + list_add_tail( &sync->wait_queue, &entry->entry ); return 1; }
@@ -1337,17 +1355,8 @@ static int select_on( const union select_op *select_op, data_size_t op_size, cli /* attempt to wake threads sleeping on the object wait queue */ void wake_up( struct object *obj, int max ) { - struct list *ptr; - int ret; - - LIST_FOR_EACH( ptr, &obj->wait_queue ) - { - struct wait_queue_entry *entry = LIST_ENTRY( ptr, struct wait_queue_entry, entry ); - if (!(ret = wake_thread( get_wait_queue_thread( entry )))) continue; - if (ret > 0 && max && !--max) break; - /* restart at the head of the list since a wake up can change the object wait queue */ - ptr = &obj->wait_queue; - } + struct sync *sync = obj->ops->get_sync( obj ); + sync_wake_up( sync, max ); }
/* return the apc queue to use for a given apc type */ diff --git a/server/thread.h b/server/thread.h index 7fdae3a629f..270bc7ed096 100644 --- a/server/thread.h +++ b/server/thread.h @@ -50,6 +50,7 @@ struct inflight_fd struct thread { struct object obj; /* object header */ + struct sync *sync; /* object sync */ struct list entry; /* entry in system-wide thread list */ struct list proc_entry; /* entry in per-process thread list */ struct list desktop_entry; /* entry in per-desktop thread list */ diff --git a/server/timer.c b/server/timer.c index 50cb7a618e5..8dec11e77c7 100644 --- a/server/timer.c +++ b/server/timer.c @@ -53,6 +53,7 @@ struct type_descr timer_type = struct timer { struct object obj; /* object header */ + struct sync *sync; /* object sync */ int manual; /* manual reset */ int signaled; /* current signaled state */ unsigned int period; /* timer period in ms */ @@ -71,6 +72,8 @@ static void timer_destroy( struct object *obj );
static const struct sync_ops timer_sync_ops = { + sizeof(struct sync), /* size */ + sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ timer_signaled, /* signaled */ @@ -110,7 +113,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->sync = alloc_sync( &timer_sync_ops ); timer->manual = manual; timer->signaled = 0; timer->when = 0; @@ -212,7 +215,7 @@ static struct sync *timer_get_sync( struct object *obj ) { struct timer *timer = (struct timer *)obj; assert( obj->ops == &timer_ops ); - return &timer->obj.sync; + return timer->sync; }
static int timer_signaled( struct object *obj, struct wait_queue_entry *entry ) @@ -236,6 +239,7 @@ static void timer_destroy( struct object *obj )
if (timer->timeout) remove_timeout_user( timer->timeout ); if (timer->thread) release_object( timer->thread ); + release_sync( timer->sync ); }
/* create a timer */
From: Rémi Bernon rbernon@codeweavers.com
--- server/async.c | 8 ++++---- server/completion.c | 12 ++++++------ server/console.c | 26 +++++++++++++------------- server/debugger.c | 8 ++++---- server/device.c | 4 ++-- server/event.c | 18 ++++++++---------- server/fd.c | 8 ++++---- server/mutex.c | 12 ++++++------ server/object.c | 6 +++--- server/object.h | 16 ++++++++-------- server/process.c | 12 ++++++------ server/queue.c | 23 ++++++++++------------- server/semaphore.c | 12 ++++++------ server/thread.c | 31 +++++++++++++++---------------- server/thread.h | 4 ++-- server/timer.c | 8 ++++---- 16 files changed, 101 insertions(+), 107 deletions(-)
diff --git a/server/async.c b/server/async.c index 399fb530789..98a9f2fcf7e 100644 --- a/server/async.c +++ b/server/async.c @@ -68,8 +68,8 @@ 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 int async_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static void async_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void async_destroy( struct object *obj );
static const struct sync_ops async_sync_ops = @@ -122,14 +122,14 @@ static struct sync *async_get_sync( struct object *obj ) return async->sync; }
-static int async_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int async_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct async *async = (struct async *)obj; assert( obj->ops == &async_ops ); return async->signaled; }
-static void async_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void async_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct async *async = (struct async *)obj; assert( obj->ops == &async_ops ); diff --git a/server/completion.c b/server/completion.c index cf3588c4267..c5e0ebd2d6b 100644 --- a/server/completion.c +++ b/server/completion.c @@ -83,8 +83,8 @@ 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 int completion_wait_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static void completion_wait_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void completion_wait_destroy( struct object * );
static const struct sync_ops completion_wait_sync_ops = @@ -140,7 +140,7 @@ static struct sync *completion_wait_get_sync( struct object *obj ) return wait->sync; }
-static int completion_wait_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int completion_wait_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct completion_wait *wait = (struct completion_wait *)obj;
@@ -149,7 +149,7 @@ static int completion_wait_signaled( struct object *obj, struct wait_queue_entry return wait->completion->depth; }
-static void completion_wait_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void completion_wait_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct completion_wait *wait = (struct completion_wait *)obj; struct list *msg_entry; @@ -172,7 +172,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_signaled( struct sync *sync, 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 * );
@@ -235,7 +235,7 @@ static struct sync *completion_get_sync( struct object *obj ) return completion->sync; }
-static int completion_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int completion_signaled( struct sync *sync, 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 9b0e7e2e63a..463a94d3349 100644 --- a/server/console.c +++ b/server/console.c @@ -69,14 +69,14 @@ struct console
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 int console_signaled( struct sync *sync, 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, unsigned int sharing, unsigned int options ); -static int console_add_queue( struct object *obj, struct wait_queue_entry *entry ); +static int console_add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry );
static const struct sync_ops console_sync_ops = { @@ -156,7 +156,7 @@ struct console_server
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 int console_server_signaled( struct sync *sync, 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, @@ -236,7 +236,7 @@ struct screen_buffer
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 int screen_buffer_signaled( struct sync *sync, 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, @@ -328,7 +328,7 @@ struct console_input };
static void console_input_dump( struct object *obj, int verbose ); -static int console_input_signaled( struct object *obj, struct wait_queue_entry *entry ); +static int console_input_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *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 ); @@ -396,7 +396,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 int console_output_signaled( struct sync *sync, 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, @@ -509,7 +509,7 @@ static const struct fd_ops console_connection_fd_ops = static int queue_host_ioctl( struct console_server *server, unsigned int code, unsigned int output, struct async *async, struct async_queue *queue );
-static int console_add_queue( struct object *obj, struct wait_queue_entry *entry ) +static int console_add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct console *console = (struct console*)obj; assert( obj->ops == &console_ops ); @@ -520,10 +520,10 @@ static int console_add_queue( struct object *obj, struct wait_queue_entry *entry if (console->server->term_fd == -1) queue_host_ioctl( console->server, IOCTL_CONDRV_PEEK, 0, NULL, NULL ); } - return add_queue( &console->obj, entry ); + return add_queue( sync, &console->obj, entry ); }
-static int console_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int console_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct console *console = (struct console*)obj; return console->signaled; @@ -900,7 +900,7 @@ static void screen_buffer_destroy( struct object *obj ) release_sync( screen_buffer->sync ); }
-static int screen_buffer_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int screen_buffer_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct screen_buffer *screen_buffer = (struct screen_buffer *)obj; assert( obj->ops == &screen_buffer_ops ); @@ -984,7 +984,7 @@ static struct object *console_server_lookup_name( struct object *obj, struct uni return NULL; }
-static int console_server_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int console_server_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct console_server *server = (struct console_server*)obj; assert( obj->ops == &console_server_ops ); @@ -1485,7 +1485,7 @@ static void console_input_dump( struct object *obj, int verbose ) fputs( "console Input device\n", stderr ); }
-static int console_input_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int console_input_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct console_input *console_input = (struct console_input *)obj; assert( obj->ops == &console_input_ops ); @@ -1564,7 +1564,7 @@ static void console_output_dump( struct object *obj, int verbose ) fputs( "console Output device\n", stderr ); }
-static int console_output_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int console_output_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct console_output *console_output = (struct console_output *)obj; assert( obj->ops == &console_output_ops ); diff --git a/server/debugger.c b/server/debugger.c index 576a751823d..74631630565 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -78,7 +78,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 int debug_event_signaled( struct sync *sync, 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 = @@ -114,7 +114,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 int debug_obj_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void debug_obj_destroy( struct object *obj );
static const struct sync_ops debug_obj_sync_ops = @@ -324,7 +324,7 @@ static struct sync *debug_event_get_sync( struct object *obj ) return debug_event->sync; }
-static int debug_event_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int debug_event_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct debug_event *debug_event = (struct debug_event *)obj; assert( obj->ops == &debug_event_ops ); @@ -356,7 +356,7 @@ static struct sync *debug_obj_get_sync( struct object *obj ) return debug_obj->sync; }
-static int debug_obj_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int debug_obj_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct debug_obj *debug_obj = (struct debug_obj *)obj; assert( obj->ops == &debug_obj_ops ); diff --git a/server/device.c b/server/device.c index 62dd7b70d07..45a9060bd6a 100644 --- a/server/device.c +++ b/server/device.c @@ -93,7 +93,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 int device_manager_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void device_manager_destroy( struct object *obj );
static const struct sync_ops device_manager_sync_ops = @@ -779,7 +779,7 @@ static struct sync *device_manager_get_sync( struct object *obj ) return manager->sync; }
-static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int device_manager_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct device_manager *manager = (struct device_manager *)obj;
diff --git a/server/event.c b/server/event.c index 85c9686f2c9..bca7a0010f0 100644 --- a/server/event.c +++ b/server/event.c @@ -62,9 +62,9 @@ struct event static void event_dump( struct object *obj, int verbose ); static struct sync *event_get_sync( struct object *obj ); static void event_destroy( 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); +static int event_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static void event_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static int event_signal( struct sync *sync, struct object *obj, unsigned int access ); static struct list *event_get_kernel_obj_list( struct object *obj );
static const struct sync_ops event_sync_ops = @@ -122,7 +122,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 void keyed_event_destroy( struct object *obj ); -static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *entry ); +static int keyed_event_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry );
static const struct sync_ops keyed_event_sync_ops = { @@ -223,14 +223,14 @@ static void event_destroy( struct object *obj ) release_sync( event->sync ); }
-static int event_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int event_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); return event->signaled; }
-static void event_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void event_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); @@ -238,7 +238,7 @@ static void event_satisfied( struct object *obj, struct wait_queue_entry *entry if (!event->manual_reset) event->signaled = 0; }
-static int event_signal( struct object *obj, unsigned int access ) +static int event_signal( struct sync *sync, struct object *obj, unsigned int access ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); @@ -303,10 +303,8 @@ static enum select_opcode matching_op( enum select_opcode op ) return op ^ (SELECT_KEYED_EVENT_WAIT ^ SELECT_KEYED_EVENT_RELEASE); }
-static int keyed_event_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int keyed_event_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { - struct keyed_event *event = (struct keyed_event *)obj; - struct sync *sync = event->sync; struct wait_queue_entry *ptr; struct process *process; enum select_opcode select_op; diff --git a/server/fd.c b/server/fd.c index aa16f097f40..6a9c1ecfe1f 100644 --- a/server/fd.c +++ b/server/fd.c @@ -159,7 +159,7 @@ 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 int fd_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void fd_destroy( struct object *obj );
const struct sync_ops fd_sync_ops = @@ -285,7 +285,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 void file_lock_destroy( struct object *obj ); -static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry ); +static int file_lock_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry );
static const struct sync_ops file_lock_sync_ops = { @@ -1262,7 +1262,7 @@ static void file_lock_destroy( struct object *obj ) release_sync( lock->sync ); }
-static int file_lock_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int file_lock_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct file_lock *lock = (struct file_lock *)obj; /* lock is signaled if it has lost its owner */ @@ -2203,7 +2203,7 @@ int check_fd_events( struct fd *fd, int events ) return pfd.revents; }
-static int fd_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int fd_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct fd *fd = get_obj_fd( obj ); int ret = fd->signaled; diff --git a/server/mutex.c b/server/mutex.c index 493f7f60ad7..761da93dd1f 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -62,10 +62,10 @@ 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 int mutex_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static void mutex_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void mutex_destroy( struct object *obj ); -static int mutex_signal( struct object *obj, unsigned int access ); +static int mutex_signal( struct sync *sync, struct object *obj, unsigned int access );
static const struct sync_ops mutex_sync_ops = { @@ -170,14 +170,14 @@ static struct sync *mutex_get_sync( struct object *obj ) return mutex->sync; }
-static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int mutex_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); return (!mutex->count || (mutex->owner == get_wait_queue_thread( entry ))); }
-static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void mutex_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); @@ -187,7 +187,7 @@ static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry mutex->abandoned = 0; }
-static int mutex_signal( struct object *obj, unsigned int access ) +static int mutex_signal( struct sync *sync, struct object *obj, unsigned int access ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); diff --git a/server/object.c b/server/object.c index eead499e2c4..611fb1d9104 100644 --- a/server/object.c +++ b/server/object.c @@ -659,17 +659,17 @@ struct namespace *create_namespace( unsigned int hash_size )
/* functions for unimplemented/default object operations */
-int no_add_queue( struct object *obj, struct wait_queue_entry *entry ) +int no_add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); return 0; }
-void no_satisfied( struct object *obj, struct wait_queue_entry *entry ) +void no_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { }
-int no_signal( struct object *obj, unsigned int access ) +int no_signal( struct sync *sync, struct object *obj, unsigned int access ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); return 0; diff --git a/server/object.h b/server/object.h index 08ee577a91a..265478bb459 100644 --- a/server/object.h +++ b/server/object.h @@ -72,15 +72,15 @@ struct sync_ops /* destroy a sync object */ void (*destroy)(struct sync *); /* add a thread to the object wait queue */ - int (*add_queue)(struct object *,struct wait_queue_entry *); + int (*add_queue)(struct sync *,struct object *,struct wait_queue_entry *); /* remove a thread from the object wait queue */ - void (*remove_queue)(struct object *,struct wait_queue_entry *); + void (*remove_queue)(struct sync *,struct object *,struct wait_queue_entry *); /* is object signaled? */ - int (*signaled)(struct object *,struct wait_queue_entry *); + int (*signaled)(struct sync *,struct object *,struct wait_queue_entry *); /* wait satisfied */ - void (*satisfied)(struct object *,struct wait_queue_entry *); + void (*satisfied)(struct sync *,struct object *,struct wait_queue_entry *); /* signal an object */ - int (*signal)(struct object *, unsigned int); + int (*signal)(struct sync *,struct object *, unsigned int); };
struct sync @@ -187,9 +187,9 @@ extern void release_sync( void *obj ); extern struct object *find_object( const struct namespace *namespace, const struct unicode_str *name, unsigned int attributes ); extern struct object *find_object_index( const struct namespace *namespace, unsigned int index ); -extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry ); -extern void no_satisfied( struct object *obj, struct wait_queue_entry *entry ); -extern int no_signal( struct object *obj, unsigned int access ); +extern int no_add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +extern void no_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +extern int no_signal( struct sync *sync, struct object *obj, unsigned int access ); extern void sync_destroy( struct sync *obj ); extern struct fd *no_get_fd( struct object *obj ); extern struct sync *no_get_sync( struct object *obj ); diff --git a/server/process.c b/server/process.c index 0201f92c44a..7edb5d2d1a6 100644 --- a/server/process.c +++ b/server/process.c @@ -90,7 +90,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 int process_signaled( struct sync *sync, 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 ); static void process_poll_event( struct fd *fd, int event ); @@ -155,7 +155,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 int startup_info_signaled( struct sync *sync, 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 = @@ -207,7 +207,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_signaled( struct sync *sync, 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 );
@@ -485,7 +485,7 @@ static struct sync *job_get_sync( struct object *obj ) return job->sync; }
-static int job_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int job_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct job *job = (struct job *)obj; return job->signaled; @@ -840,7 +840,7 @@ static struct sync *process_get_sync( struct object *obj ) return process->sync; }
-static int process_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int process_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct process *process = (struct process *)obj; return !process->running_threads; @@ -938,7 +938,7 @@ static struct sync *startup_info_get_sync( struct object *obj ) return info->sync; }
-static int startup_info_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int startup_info_signaled( struct sync *sync, 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; diff --git a/server/queue.c b/server/queue.c index d833fac033a..961eb7855e0 100644 --- a/server/queue.c +++ b/server/queue.c @@ -149,10 +149,10 @@ 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 ); -static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry ); +static int msg_queue_add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static void msg_queue_remove_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static int msg_queue_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static void msg_queue_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void msg_queue_destroy( struct object *obj ); static void msg_queue_poll_event( struct fd *fd, int event ); static void thread_input_dump( struct object *obj, int verbose ); @@ -1278,10 +1278,9 @@ static int is_queue_hung( struct msg_queue *queue ) return 1; }
-static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry ) +static int msg_queue_add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; - struct sync *sync = queue->sync;
/* a thread can only wait on its own queue */ if (get_wait_queue_thread(entry)->queue != queue) @@ -1292,16 +1291,15 @@ static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *ent
if (queue->fd && list_empty( &sync->wait_queue )) /* first on the queue */ set_fd_events( queue->fd, POLLIN ); - add_queue( obj, entry ); + add_queue( sync, obj, entry ); return 1; }
-static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry ) +static void msg_queue_remove_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; - struct sync *sync = queue->sync;
- remove_queue( obj, entry ); + remove_queue( sync, obj, entry ); if (queue->fd && list_empty( &sync->wait_queue )) /* last on the queue is gone */ set_fd_events( queue->fd, 0 ); } @@ -1321,10 +1319,9 @@ static struct sync *msg_queue_get_sync( struct object *obj ) return queue->sync; }
-static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int msg_queue_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; - struct sync *sync = queue->sync; int ret = 0;
if (queue->fd) @@ -1339,7 +1336,7 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr return ret || is_signaled( queue ); }
-static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void msg_queue_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; const queue_shm_t *queue_shm = queue->shared; diff --git a/server/semaphore.c b/server/semaphore.c index 716baf87369..95f9a8f7fa3 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -61,9 +61,9 @@ struct semaphore static void semaphore_dump( struct object *obj, int verbose ); static struct sync *semaphore_get_sync( struct object *obj ); static void semaphore_destroy( 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 ); +static int semaphore_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static void semaphore_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static int semaphore_signal( struct sync *sync, struct object *obj, unsigned int access );
static const struct sync_ops semaphore_sync_ops = { @@ -164,14 +164,14 @@ static void semaphore_destroy( struct object *obj ) release_sync( semaphore->sync ); }
-static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int semaphore_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); return (sem->count > 0); }
-static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void semaphore_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); @@ -179,7 +179,7 @@ static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *en sem->count--; }
-static int semaphore_signal( struct object *obj, unsigned int access ) +static int semaphore_signal( struct sync *sync, struct object *obj, unsigned int access ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); diff --git a/server/thread.c b/server/thread.c index 43e09728f01..8774917b7c9 100644 --- a/server/thread.c +++ b/server/thread.c @@ -96,7 +96,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 int thread_apc_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void thread_apc_destroy( struct object *obj ); static void clear_apc_queue( struct list *queue );
@@ -150,7 +150,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 void context_destroy( struct object *obj ); -static int context_signaled( struct object *obj, struct wait_queue_entry *entry ); +static int context_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry );
static const struct sync_ops context_sync_ops = { @@ -203,7 +203,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 int thread_signaled( struct sync *sync, 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 ); static struct list *thread_get_kernel_obj_list( struct object *obj ); @@ -486,7 +486,7 @@ static void context_destroy( struct object *obj ) release_sync( context->sync ); }
-static int context_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int context_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct context *context = (struct context *)obj; return context->status != STATUS_PENDING; @@ -681,7 +681,7 @@ static struct sync *thread_get_sync( struct object *obj ) return thread->sync; }
-static int thread_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int thread_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct thread *mythread = (struct thread *)obj; return (mythread->state == TERMINATED); @@ -710,7 +710,7 @@ static struct sync *thread_apc_get_sync( struct object *obj ) return apc->sync; }
-static int thread_apc_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int thread_apc_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct thread_apc *apc = (struct thread_apc *)obj; return apc->executed; @@ -977,9 +977,8 @@ int resume_thread( struct thread *thread ) }
/* add a thread to an object wait queue; return 1 if OK, 0 on error */ -int add_queue( struct object *obj, struct wait_queue_entry *entry ) +int add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { - struct sync *sync = obj->ops->get_sync( obj ); grab_object( obj ); entry->obj = obj; list_add_tail( &sync->wait_queue, &entry->entry ); @@ -987,7 +986,7 @@ int add_queue( struct object *obj, struct wait_queue_entry *entry ) }
/* remove a thread from an object wait queue */ -void remove_queue( struct object *obj, struct wait_queue_entry *entry ) +void remove_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { list_remove( &entry->entry ); release_object( obj ); @@ -1036,7 +1035,7 @@ static unsigned int end_wait( struct thread *thread, unsigned int status ) for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) { struct sync *sync = entry->obj->ops->get_sync( entry->obj ); - sync->ops->satisfied( entry->obj, entry ); + sync->ops->satisfied( sync, entry->obj, entry ); } } else @@ -1044,7 +1043,7 @@ static unsigned int end_wait( struct thread *thread, unsigned int status ) struct sync *sync; entry = wait->queues + status; sync = entry->obj->ops->get_sync( entry->obj ); - sync->ops->satisfied( entry->obj, entry ); + sync->ops->satisfied( sync, entry->obj, entry ); } status = wait->status; if (wait->abandoned) status += STATUS_ABANDONED_WAIT_0; @@ -1052,7 +1051,7 @@ static unsigned int end_wait( struct thread *thread, unsigned int status ) for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) { struct sync *sync = entry->obj->ops->get_sync( entry->obj ); - sync->ops->remove_queue( entry->obj, entry ); + sync->ops->remove_queue( sync, entry->obj, entry ); } if (wait->user) remove_timeout_user( wait->user ); free( wait ); @@ -1084,7 +1083,7 @@ static int wait_on( const union select_op *select_op, unsigned int count, struct struct object *obj = objects[i]; struct sync *sync = obj->ops->get_sync( obj ); entry->wait = wait; - if (!sync->ops->add_queue( obj, entry )) + if (!sync->ops->add_queue( sync, obj, entry )) { wait->count = i; end_wait( current, get_error() ); @@ -1140,7 +1139,7 @@ static int check_wait( struct thread *thread ) for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) { struct sync *sync = entry->obj->ops->get_sync( entry->obj ); - not_ok |= !sync->ops->signaled( entry->obj, entry ); + not_ok |= !sync->ops->signaled( sync, entry->obj, entry ); } if (!not_ok) return STATUS_WAIT_0; } @@ -1149,7 +1148,7 @@ static int check_wait( struct thread *thread ) for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) { struct sync *sync = entry->obj->ops->get_sync( entry->obj ); - if (sync->ops->signaled( entry->obj, entry )) return i; + if (sync->ops->signaled( sync, entry->obj, entry )) return i; } }
@@ -1267,7 +1266,7 @@ static int signal_object( obj_handle_t handle ) if (obj) { struct sync *sync = obj->ops->get_sync( obj ); - ret = sync->ops->signal( obj, get_handle_access( current->process, handle ) ); + ret = sync->ops->signal( sync, obj, get_handle_access( current->process, handle ) ); release_object( obj ); } return ret; diff --git a/server/thread.h b/server/thread.h index 270bc7ed096..2ff31043287 100644 --- a/server/thread.h +++ b/server/thread.h @@ -115,8 +115,8 @@ extern void set_wait_status( struct wait_queue_entry *entry, int status ); extern void stop_thread( struct thread *thread ); extern int wake_thread( struct thread *thread ); extern int wake_thread_queue_entry( struct wait_queue_entry *entry ); -extern int add_queue( struct object *obj, struct wait_queue_entry *entry ); -extern void remove_queue( struct object *obj, struct wait_queue_entry *entry ); +extern int add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +extern void remove_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); extern void kill_thread( struct thread *thread, int violent_death ); extern void wake_up( struct object *obj, int max ); extern int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const union apc_call *call_data ); diff --git a/server/timer.c b/server/timer.c index 8dec11e77c7..46190659e4e 100644 --- a/server/timer.c +++ b/server/timer.c @@ -66,8 +66,8 @@ 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 int timer_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); +static void timer_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void timer_destroy( struct object *obj );
static const struct sync_ops timer_sync_ops = @@ -218,14 +218,14 @@ static struct sync *timer_get_sync( struct object *obj ) return timer->sync; }
-static int timer_signaled( struct object *obj, struct wait_queue_entry *entry ) +static int timer_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct timer *timer = (struct timer *)obj; assert( obj->ops == &timer_ops ); return timer->signaled; }
-static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry ) +static void timer_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { struct timer *timer = (struct timer *)obj; assert( obj->ops == &timer_ops );
From: Rémi Bernon rbernon@codeweavers.com
--- server/event.c | 8 +++++--- server/mutex.c | 10 ++++++---- server/object.c | 2 +- server/object.h | 8 +++++--- server/semaphore.c | 8 +++++--- server/thread.c | 2 +- 6 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/server/event.c b/server/event.c index bca7a0010f0..f0565757670 100644 --- a/server/event.c +++ b/server/event.c @@ -64,7 +64,7 @@ static struct sync *event_get_sync( struct object *obj ); static void event_destroy( struct object *obj ); static int event_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void event_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); -static int event_signal( struct sync *sync, struct object *obj, unsigned int access ); +static int event_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ); static struct list *event_get_kernel_obj_list( struct object *obj );
static const struct sync_ops event_sync_ops = @@ -238,16 +238,18 @@ static void event_satisfied( struct sync *sync, struct object *obj, struct wait_ if (!event->manual_reset) event->signaled = 0; }
-static int event_signal( struct sync *sync, struct object *obj, unsigned int access ) +static int event_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops );
- if (!(access & EVENT_MODIFY_STATE)) + if (signal == SIGNAL_SELECT && !(access & EVENT_MODIFY_STATE)) { set_error( STATUS_ACCESS_DENIED ); return 0; } + + assert( signal == SIGNAL_SELECT ); set_event( event ); return 1; } diff --git a/server/mutex.c b/server/mutex.c index 761da93dd1f..42a5c3500a1 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -65,7 +65,7 @@ static struct sync *mutex_get_sync( struct object *obj ); static int mutex_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void mutex_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void mutex_destroy( struct object *obj ); -static int mutex_signal( struct sync *sync, struct object *obj, unsigned int access ); +static int mutex_signal( struct sync *sync, struct object *obj, int signal, unsigned int access );
static const struct sync_ops mutex_sync_ops = { @@ -187,21 +187,23 @@ static void mutex_satisfied( struct sync *sync, struct object *obj, struct wait_ mutex->abandoned = 0; }
-static int mutex_signal( struct sync *sync, struct object *obj, unsigned int access ) +static int mutex_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops );
- if (!(access & SYNCHRONIZE)) + if (signal == SIGNAL_SELECT && !(access & SYNCHRONIZE)) { set_error( STATUS_ACCESS_DENIED ); return 0; } - if (!mutex->count || (mutex->owner != current)) + if (signal == SIGNAL_SELECT && (!mutex->count || (mutex->owner != current))) { set_error( STATUS_MUTANT_NOT_OWNED ); return 0; } + + assert( signal == SIGNAL_SELECT ); if (!--mutex->count) do_release( mutex ); return 1; } diff --git a/server/object.c b/server/object.c index 611fb1d9104..1704bea1b98 100644 --- a/server/object.c +++ b/server/object.c @@ -669,7 +669,7 @@ void no_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entr { }
-int no_signal( struct sync *sync, struct object *obj, unsigned int access ) +int no_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); return 0; diff --git a/server/object.h b/server/object.h index 265478bb459..e822106d86e 100644 --- a/server/object.h +++ b/server/object.h @@ -64,6 +64,8 @@ struct type_descr unsigned int handle_max; /* max count of handles of this type */ };
+#define SIGNAL_SELECT -1 /* sync is being signaled from select */ + /* operations valid on waitable objects */ struct sync_ops { @@ -79,8 +81,8 @@ struct sync_ops int (*signaled)(struct sync *,struct object *,struct wait_queue_entry *); /* wait satisfied */ void (*satisfied)(struct sync *,struct object *,struct wait_queue_entry *); - /* signal an object */ - int (*signal)(struct sync *,struct object *, unsigned int); + /* signal/reset a sync, signal is SIGNAL_SELECT when signaled from select */ + int (*signal)(struct sync *,struct object *,int,unsigned int); };
struct sync @@ -189,7 +191,7 @@ extern struct object *find_object( const struct namespace *namespace, const stru extern struct object *find_object_index( const struct namespace *namespace, unsigned int index ); extern int no_add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); extern void no_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); -extern int no_signal( struct sync *sync, struct object *obj, unsigned int access ); +extern int no_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ); extern void sync_destroy( struct sync *obj ); extern struct fd *no_get_fd( struct object *obj ); extern struct sync *no_get_sync( struct object *obj ); diff --git a/server/semaphore.c b/server/semaphore.c index 95f9a8f7fa3..1ebf7c435ea 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -63,7 +63,7 @@ static struct sync *semaphore_get_sync( struct object *obj ); static void semaphore_destroy( struct object *obj ); static int semaphore_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); static void semaphore_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); -static int semaphore_signal( struct sync *sync, struct object *obj, unsigned int access ); +static int semaphore_signal( struct sync *sync, struct object *obj, int signal, unsigned int access );
static const struct sync_ops semaphore_sync_ops = { @@ -179,16 +179,18 @@ static void semaphore_satisfied( struct sync *sync, struct object *obj, struct w sem->count--; }
-static int semaphore_signal( struct sync *sync, struct object *obj, unsigned int access ) +static int semaphore_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops );
- if (!(access & SEMAPHORE_MODIFY_STATE)) + if (signal == SIGNAL_SELECT && !(access & SEMAPHORE_MODIFY_STATE)) { set_error( STATUS_ACCESS_DENIED ); return 0; } + + assert( signal == SIGNAL_SELECT ); return release_semaphore( sem, 1, NULL ); }
diff --git a/server/thread.c b/server/thread.c index 8774917b7c9..0ded4076d82 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1266,7 +1266,7 @@ static int signal_object( obj_handle_t handle ) if (obj) { struct sync *sync = obj->ops->get_sync( obj ); - ret = sync->ops->signal( sync, obj, get_handle_access( current->process, handle ) ); + ret = sync->ops->signal( sync, obj, SIGNAL_SELECT, get_handle_access( current->process, handle ) ); release_object( obj ); } return ret;
From: Rémi Bernon rbernon@codeweavers.com
--- server/event.c | 69 +++++++++++++++++++++++++++++++------------------ server/object.c | 12 +++++++++ server/object.h | 2 ++ 3 files changed, 58 insertions(+), 25 deletions(-)
diff --git a/server/event.c b/server/event.c index f0565757670..500d95bb8e0 100644 --- a/server/event.c +++ b/server/event.c @@ -50,13 +50,18 @@ struct type_descr event_type = }, };
+struct event_sync +{ + struct sync sync; /* sync header */ + unsigned int manual_reset :1; /* is it a manual reset event? */ + unsigned int signaled :1; /* event has been signaled */ +}; + struct event { struct object obj; /* object header */ struct sync *sync; /* object sync */ struct list kernel_object; /* list of kernel object pointers */ - int manual_reset; /* is it a manual reset event? */ - int signaled; /* event has been signaled */ };
static void event_dump( struct object *obj, int verbose ); @@ -69,7 +74,7 @@ static struct list *event_get_kernel_obj_list( struct object *obj );
static const struct sync_ops event_sync_ops = { - sizeof(struct sync), /* size */ + sizeof(struct event_sync), /* size */ sync_destroy, /* destroy */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ @@ -155,6 +160,15 @@ static const struct object_ops keyed_event_ops = keyed_event_destroy, /* destroy */ };
+static struct sync *create_event_sync( int manual_reset, int initial_state ) +{ + struct event_sync *event; + + event = (struct event_sync *)alloc_sync( &event_sync_ops ); + event->manual_reset = manual_reset; + event->signaled = initial_state; + return &event->sync; +}
struct event *create_event( struct object *root, const struct unicode_str *name, unsigned int attr, int manual_reset, int initial_state, @@ -167,10 +181,8 @@ struct event *create_event( struct object *root, const struct unicode_str *name, if (get_error() != STATUS_OBJECT_NAME_EXISTS) { /* initialize it if it didn't already exist */ - event->sync = alloc_sync( &event_sync_ops ); + event->sync = create_event_sync( manual_reset, initial_state ); list_init( &event->kernel_object ); - event->manual_reset = manual_reset; - event->signaled = initial_state; } } return event; @@ -181,32 +193,32 @@ struct event *get_event_obj( struct process *process, obj_handle_t handle, unsig return (struct event *)get_handle_obj( process, handle, access, &event_ops ); }
-static void pulse_event( struct event *event ) +static void pulse_event( struct event_sync *event ) { event->signaled = 1; /* wake up all waiters if manual reset, a single one otherwise */ - wake_up( &event->obj, !event->manual_reset ); + sync_wake_up( &event->sync, !event->manual_reset ); event->signaled = 0; }
void set_event( struct event *event ) { - event->signaled = 1; - /* wake up all waiters if manual reset, a single one otherwise */ - wake_up( &event->obj, !event->manual_reset ); + signal_sync( &event->obj ); }
void reset_event( struct event *event ) { - event->signaled = 0; + reset_sync( &event->obj ); }
static void event_dump( struct object *obj, int verbose ) { struct event *event = (struct event *)obj; + struct event_sync *sync = (struct event_sync *)event->sync; assert( obj->ops == &event_ops ); + assert( event->sync->ops == &event_sync_ops ); fprintf( stderr, "Event manual=%d signaled=%d\n", - event->manual_reset, event->signaled ); + sync->manual_reset, sync->signaled ); }
static struct sync *event_get_sync( struct object *obj ) @@ -225,23 +237,23 @@ static void event_destroy( struct object *obj )
static int event_signaled( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { - struct event *event = (struct event *)obj; - assert( obj->ops == &event_ops ); + struct event_sync *event = (struct event_sync *)sync; + assert( sync->ops == &event_sync_ops ); return event->signaled; }
static void event_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ) { - struct event *event = (struct event *)obj; - assert( obj->ops == &event_ops ); + struct event_sync *event = (struct event_sync *)sync; + assert( sync->ops == &event_sync_ops ); /* Reset if it's an auto-reset event */ if (!event->manual_reset) event->signaled = 0; }
static int event_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ) { - struct event *event = (struct event *)obj; - assert( obj->ops == &event_ops ); + struct event_sync *event = (struct event_sync *)sync; + assert( sync->ops == &event_sync_ops );
if (signal == SIGNAL_SELECT && !(access & EVENT_MODIFY_STATE)) { @@ -249,8 +261,8 @@ static int event_signal( struct sync *sync, struct object *obj, int signal, unsi return 0; }
- assert( signal == SIGNAL_SELECT ); - set_event( event ); + /* wake up all waiters if manual reset, a single one otherwise */ + if ((event->signaled = !!signal)) sync_wake_up( &event->sync, !event->manual_reset ); return 1; }
@@ -365,14 +377,18 @@ DECL_HANDLER(open_event) /* do an event operation */ DECL_HANDLER(event_op) { + struct event_sync *sync; struct event *event;
if (!(event = get_event_obj( current->process, req->handle, EVENT_MODIFY_STATE ))) return; - reply->state = event->signaled; + sync = (struct event_sync *)event->sync; + assert( event->sync->ops == &event_sync_ops ); + + reply->state = sync->signaled; switch(req->op) { case PULSE_EVENT: - pulse_event( event ); + pulse_event( sync ); break; case SET_EVENT: set_event( event ); @@ -390,12 +406,15 @@ DECL_HANDLER(event_op) /* return details about the event */ DECL_HANDLER(query_event) { + struct event_sync *sync; struct event *event;
if (!(event = get_event_obj( current->process, req->handle, EVENT_QUERY_STATE ))) return; + sync = (struct event_sync *)event->sync; + assert( event->sync->ops == &event_sync_ops );
- reply->manual_reset = event->manual_reset; - reply->state = event->signaled; + reply->manual_reset = sync->manual_reset; + reply->state = sync->signaled;
release_object( event ); } diff --git a/server/object.c b/server/object.c index 1704bea1b98..a38078d09bd 100644 --- a/server/object.c +++ b/server/object.c @@ -675,6 +675,18 @@ int no_signal( struct sync *sync, struct object *obj, int signal, unsigned int a return 0; }
+int signal_sync( struct object *obj ) +{ + struct sync *sync = obj->ops->get_sync( obj ); + return sync->ops->signal( sync, obj, 1, 0 ); +} + +int reset_sync( struct object *obj ) +{ + struct sync *sync = obj->ops->get_sync( obj ); + return sync->ops->signal( sync, obj, 0, 0 ); +} + void sync_destroy( struct sync *obj ) { struct sync *sync = (struct sync *)obj; diff --git a/server/object.h b/server/object.h index e822106d86e..2571e0d54b7 100644 --- a/server/object.h +++ b/server/object.h @@ -192,6 +192,8 @@ extern struct object *find_object_index( const struct namespace *namespace, unsi extern int no_add_queue( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); extern void no_satisfied( struct sync *sync, struct object *obj, struct wait_queue_entry *entry ); extern int no_signal( struct sync *sync, struct object *obj, int signal, unsigned int access ); +extern int signal_sync( struct object *obj ); +extern int reset_sync( struct object *obj ); extern void sync_destroy( struct sync *obj ); extern struct fd *no_get_fd( struct object *obj ); extern struct sync *no_get_sync( struct object *obj );
Unlike how the fd struct have been implemented, I chose not to derive these syncs from the object base, because it seemed inconvenient to have to declare all the unused ops. Still they are refcounted, to allow us to share a sync between multiple objects, which will later benefit the console objects use cases, maybe others.
This makes me thing that the fd struct could also benefit from being lightweight entities as well, as it doesn't seem they really use most of the object vtable ops, and arguably we could have a common "light" refcounted/dumpable base for all fds, syncs and objects, but I didn't want to jump into that rabbit hole and it could be implemented later.
This was of course the original intent of the object struct. There has been a bit of feature creep, but I don't think it's bad enough to justify adding a parallel infrastructure for these.
I'm not convinced we need a refcounted struct sync at all, but if we do, it should be a proper object.
Alright, lets do it differently then, moving most objects to use events for their wait/signal ops so we only need to change/split a couple of objects for ntsync later on.
This merge request was closed by Rémi Bernon.