# HG changeset patch # User Paul Boddie # Date 1679502665 -3600 # Node ID b33673595ce04cd41d61cebd815eee2bf2b42a2e # Parent 07dd3f43693ea16e974ca8b7e1a6ac485d2db4a4 Separated auto-deletion from general notifications related to IPC. diff -r 07dd3f43693e -r b33673595ce0 libipc/include/ipc/server.h --- a/libipc/include/ipc/server.h Wed Mar 22 16:15:04 2023 +0100 +++ b/libipc/include/ipc/server.h Wed Mar 22 17:31:05 2023 +0100 @@ -86,6 +86,7 @@ int notifications; l4_cap_idx_t irq; + int auto_deletion; } ipc_server_config_type; @@ -100,13 +101,17 @@ -/* Associate a notification IRQ with an IPC gate in the main thread. */ +/* Associate a notification IRQ with the main thread. */ -long ipc_server_apply_irq(l4_cap_idx_t cap, l4_cap_idx_t *irq); +long ipc_server_apply_irq(l4_cap_idx_t *irq); + +/* Associate a notification IRQ with the given thread. */ -/* Associate a notification IRQ with an IPC gate in the given thread. */ +long ipc_server_apply_irq_for_thread(l4_cap_idx_t *irq, l4_cap_idx_t thread); -long ipc_server_apply_irq_for_thread(l4_cap_idx_t cap, l4_cap_idx_t *irq, l4_cap_idx_t thread); +/* Apply auto-deletion to an IRQ associated with the given thread. */ + +long ipc_server_apply_deletion_for_thread(l4_cap_idx_t cap, l4_cap_idx_t irq, l4_cap_idx_t thread); /* Bind the main thread to a named IPC gate capability. */ diff -r 07dd3f43693e -r b33673595ce0 libipc/lib/src/server.c --- a/libipc/lib/src/server.c Wed Mar 22 16:15:04 2023 +0100 +++ b/libipc/lib/src/server.c Wed Mar 22 17:31:05 2023 +0100 @@ -34,18 +34,16 @@ -/* Associate an IRQ with the IPC gate in the main thread to handle gate deletion - notifications. */ +/* Associate an IRQ with the main thread. */ -long ipc_server_apply_irq(l4_cap_idx_t cap, l4_cap_idx_t *irq) +long ipc_server_apply_irq(l4_cap_idx_t *irq) { - return ipc_server_apply_irq_for_thread(cap, irq, l4re_env()->main_thread); + return ipc_server_apply_irq_for_thread(irq, l4re_env()->main_thread); } -/* Associate an IRQ with the IPC gate in the given thread to handle gate deletion - notifications. */ +/* Associate an IRQ with the given thread. */ -long ipc_server_apply_irq_for_thread(l4_cap_idx_t cap, l4_cap_idx_t *irq, l4_cap_idx_t thread) +long ipc_server_apply_irq_for_thread(l4_cap_idx_t *irq, l4_cap_idx_t thread) { /* Create an IRQ for the gate. */ @@ -65,14 +63,23 @@ return err; } + return L4_EOK; +} + +/* Associate the given IRQ with gate deletion notifications, also decreasing the + IPC gate reference count so that such a notification will be delivered when + the final client of the IPC gate releases its reference to it. */ + +long ipc_server_apply_deletion_for_thread(l4_cap_idx_t cap, l4_cap_idx_t irq, l4_cap_idx_t thread) +{ /* Register for notifications. The thread associated with the gate seems to be needed. */ - err = l4_error(l4_thread_register_del_irq(thread, *irq)); + long err = l4_error(l4_thread_register_del_irq(thread, irq)); if (err) { - ipc_cap_free_um(*irq); + ipc_cap_free_um(irq); return err; } @@ -249,7 +256,7 @@ irq_label = (l4_umword_t) config->irq; - if (!config->notifications || (config->notifications && (label != irq_label))) + if (label != irq_label) { config_from_label = (ipc_server_config_type *) label; config_from_label->handler(&msg, config_from_label->handler_obj); @@ -257,7 +264,7 @@ /* Message involves the IRQ or a termination condition occurred. */ - else if ((config->notifications && (label == irq_label)) || msg.terminating) + else if ((label == irq_label) || msg.terminating) break; } @@ -355,10 +362,12 @@ config->thread = l4re_env()->main_thread; config->server = L4_INVALID_CAP; - /* No notifications and with IRQ to be potentially allocated. */ + /* No notifications and with IRQ to be potentially allocated. Auto-deletion is + also disabled by default. */ config->notifications = 0; config->irq = L4_INVALID_CAP; + config->auto_deletion = 0; } /* Initialise but do not start a server using the given configuration. */ @@ -381,11 +390,21 @@ if (config->notifications) { - err = ipc_server_apply_irq_for_thread(config->server, &config->irq, config->thread); + err = ipc_server_apply_irq_for_thread(&config->irq, config->thread); if (err) return err; + /* Apply auto-deletion if appropriate. */ + + if (config->auto_deletion) + { + err = ipc_server_apply_deletion_for_thread(config->server, config->irq, config->thread); + + if (err) + return err; + } + /* Unmask the interrupt. */ ipc_init_irq(config->irq); diff -r 07dd3f43693e -r b33673595ce0 libnotifier/lib/src/notifier.cc --- a/libnotifier/lib/src/notifier.cc Wed Mar 22 16:15:04 2023 +0100 +++ b/libnotifier/lib/src/notifier.cc Wed Mar 22 17:31:05 2023 +0100 @@ -103,7 +103,7 @@ NotifierResource *notifier = new NotifierResource; ResourceServer server(notifier); - long err = server.start_thread(false); + long err = server.start_thread(true, false); if (err) return err; @@ -152,7 +152,7 @@ NotifierResource *resource = new NotifierResource(this, object); ResourceServer server(resource); - long err = server.start_in_thread(_configs.front()->thread, false); + long err = server.start_in_thread(_configs.front()->thread); if (err) return err; diff -r 07dd3f43693e -r b33673595ce0 libresource/include/resource/resource_server.h --- a/libresource/include/resource/resource_server.h Wed Mar 22 16:15:04 2023 +0100 +++ b/libresource/include/resource/resource_server.h Wed Mar 22 17:31:05 2023 +0100 @@ -55,11 +55,12 @@ long start(bool finalisation = false); - long start_in_thread(l4_cap_idx_t thread, bool finalisation = false); + long start_in_thread(l4_cap_idx_t thread); - long start_thread(bool finalisation = true); + long start_thread(bool finalisation = true, bool auto_deletion = true); - long start_thread(l4_cap_idx_t *server, bool finalisation = true); + long start_thread(l4_cap_idx_t *server, bool finalisation = true, + bool auto_deletion = true); }; @@ -69,8 +70,8 @@ void resource_init_config(ipc_server_config_type *config, Resource *resource); void resource_set_config_threaded(ipc_server_config_type *config, - l4_cap_idx_t thread, int new_thread, - int finalisation); + l4_cap_idx_t thread, int separate_thread, + int finalisation, int auto_deletion); /* Server initiation. */ diff -r 07dd3f43693e -r b33673595ce0 libresource/lib/src/resource_server.cc --- a/libresource/lib/src/resource_server.cc Wed Mar 22 16:15:04 2023 +0100 +++ b/libresource/lib/src/resource_server.cc Wed Mar 22 17:31:05 2023 +0100 @@ -38,8 +38,8 @@ return ipc_server_bind(name, (l4_umword_t) _config, &_config->server); } -/* Start in the same thread indicating whether deletion notifications and - finalisation are to be used. */ +/* Start in the same thread indicating whether the server can be finalised. If + so, deletion notifications will be used. */ long ResourceServer::start(bool finalisation) { @@ -56,24 +56,26 @@ { _config->finaliser = resource_same_thread_finaliser; _config->notifications = 1; + _config->auto_deletion = 1; } return resource_start_config(_config, _resource); } -/* Start serving a resource in an existing thread. */ +/* Start serving a resource in an existing thread. The resource will not be + finalised. */ -long ResourceServer::start_in_thread(l4_cap_idx_t thread, bool finalisation) +long ResourceServer::start_in_thread(l4_cap_idx_t thread) { resource_init_config(_config, _resource); - resource_set_config_threaded(_config, thread, 1, finalisation); + resource_set_config_threaded(_config, thread, 1, 0, 0); return resource_start_config(_config, _resource); } /* Start serving a resource in a new thread. */ -long ResourceServer::start_thread(bool finalisation) +long ResourceServer::start_thread(bool finalisation, bool auto_deletion) { pthread_t thread; pthread_attr_t attr; @@ -88,7 +90,8 @@ if (err) return err; - resource_set_config_threaded(_config, pthread_l4_cap(thread), 1, finalisation); + resource_set_config_threaded(_config, pthread_l4_cap(thread), 1, finalisation, + auto_deletion); return resource_start_config(_config, _resource); } @@ -96,9 +99,10 @@ /* A convenience method starting a thread and returning the server capability employed via the given parameter. */ -long ResourceServer::start_thread(l4_cap_idx_t *server, bool finalisation) +long ResourceServer::start_thread(l4_cap_idx_t *server, bool finalisation, + bool auto_deletion) { - long err = start_thread(finalisation); + long err = start_thread(finalisation, auto_deletion); if (!err) *server = _config->server; @@ -123,13 +127,16 @@ /* Set a configuration to be threaded. */ void resource_set_config_threaded(ipc_server_config_type *config, - l4_cap_idx_t thread, int new_thread, - int finalisation) + l4_cap_idx_t thread, int separate_thread, + int finalisation, int auto_deletion) { - config->finaliser = resource_thread_finaliser; - config->config_thread = new_thread; + if (finalisation) + config->finaliser = resource_thread_finaliser; + + config->config_thread = separate_thread; config->thread = thread; config->notifications = finalisation; + config->auto_deletion = auto_deletion; } /* Activate a resource and start a server for it. */