1.1 --- a/libipc/include/ipc/server.h Wed Mar 22 16:15:04 2023 +0100
1.2 +++ b/libipc/include/ipc/server.h Wed Mar 22 17:31:05 2023 +0100
1.3 @@ -86,6 +86,7 @@
1.4
1.5 int notifications;
1.6 l4_cap_idx_t irq;
1.7 + int auto_deletion;
1.8
1.9 } ipc_server_config_type;
1.10
1.11 @@ -100,13 +101,17 @@
1.12
1.13
1.14
1.15 -/* Associate a notification IRQ with an IPC gate in the main thread. */
1.16 +/* Associate a notification IRQ with the main thread. */
1.17
1.18 -long ipc_server_apply_irq(l4_cap_idx_t cap, l4_cap_idx_t *irq);
1.19 +long ipc_server_apply_irq(l4_cap_idx_t *irq);
1.20 +
1.21 +/* Associate a notification IRQ with the given thread. */
1.22
1.23 -/* Associate a notification IRQ with an IPC gate in the given thread. */
1.24 +long ipc_server_apply_irq_for_thread(l4_cap_idx_t *irq, l4_cap_idx_t thread);
1.25
1.26 -long ipc_server_apply_irq_for_thread(l4_cap_idx_t cap, l4_cap_idx_t *irq, l4_cap_idx_t thread);
1.27 +/* Apply auto-deletion to an IRQ associated with the given thread. */
1.28 +
1.29 +long ipc_server_apply_deletion_for_thread(l4_cap_idx_t cap, l4_cap_idx_t irq, l4_cap_idx_t thread);
1.30
1.31 /* Bind the main thread to a named IPC gate capability. */
1.32
2.1 --- a/libipc/lib/src/server.c Wed Mar 22 16:15:04 2023 +0100
2.2 +++ b/libipc/lib/src/server.c Wed Mar 22 17:31:05 2023 +0100
2.3 @@ -34,18 +34,16 @@
2.4
2.5
2.6
2.7 -/* Associate an IRQ with the IPC gate in the main thread to handle gate deletion
2.8 - notifications. */
2.9 +/* Associate an IRQ with the main thread. */
2.10
2.11 -long ipc_server_apply_irq(l4_cap_idx_t cap, l4_cap_idx_t *irq)
2.12 +long ipc_server_apply_irq(l4_cap_idx_t *irq)
2.13 {
2.14 - return ipc_server_apply_irq_for_thread(cap, irq, l4re_env()->main_thread);
2.15 + return ipc_server_apply_irq_for_thread(irq, l4re_env()->main_thread);
2.16 }
2.17
2.18 -/* Associate an IRQ with the IPC gate in the given thread to handle gate deletion
2.19 - notifications. */
2.20 +/* Associate an IRQ with the given thread. */
2.21
2.22 -long ipc_server_apply_irq_for_thread(l4_cap_idx_t cap, l4_cap_idx_t *irq, l4_cap_idx_t thread)
2.23 +long ipc_server_apply_irq_for_thread(l4_cap_idx_t *irq, l4_cap_idx_t thread)
2.24 {
2.25 /* Create an IRQ for the gate. */
2.26
2.27 @@ -65,14 +63,23 @@
2.28 return err;
2.29 }
2.30
2.31 + return L4_EOK;
2.32 +}
2.33 +
2.34 +/* Associate the given IRQ with gate deletion notifications, also decreasing the
2.35 + IPC gate reference count so that such a notification will be delivered when
2.36 + the final client of the IPC gate releases its reference to it. */
2.37 +
2.38 +long ipc_server_apply_deletion_for_thread(l4_cap_idx_t cap, l4_cap_idx_t irq, l4_cap_idx_t thread)
2.39 +{
2.40 /* Register for notifications. The thread associated with the gate seems to be
2.41 needed. */
2.42
2.43 - err = l4_error(l4_thread_register_del_irq(thread, *irq));
2.44 + long err = l4_error(l4_thread_register_del_irq(thread, irq));
2.45
2.46 if (err)
2.47 {
2.48 - ipc_cap_free_um(*irq);
2.49 + ipc_cap_free_um(irq);
2.50 return err;
2.51 }
2.52
2.53 @@ -249,7 +256,7 @@
2.54
2.55 irq_label = (l4_umword_t) config->irq;
2.56
2.57 - if (!config->notifications || (config->notifications && (label != irq_label)))
2.58 + if (label != irq_label)
2.59 {
2.60 config_from_label = (ipc_server_config_type *) label;
2.61 config_from_label->handler(&msg, config_from_label->handler_obj);
2.62 @@ -257,7 +264,7 @@
2.63
2.64 /* Message involves the IRQ or a termination condition occurred. */
2.65
2.66 - else if ((config->notifications && (label == irq_label)) || msg.terminating)
2.67 + else if ((label == irq_label) || msg.terminating)
2.68 break;
2.69 }
2.70
2.71 @@ -355,10 +362,12 @@
2.72 config->thread = l4re_env()->main_thread;
2.73 config->server = L4_INVALID_CAP;
2.74
2.75 - /* No notifications and with IRQ to be potentially allocated. */
2.76 + /* No notifications and with IRQ to be potentially allocated. Auto-deletion is
2.77 + also disabled by default. */
2.78
2.79 config->notifications = 0;
2.80 config->irq = L4_INVALID_CAP;
2.81 + config->auto_deletion = 0;
2.82 }
2.83
2.84 /* Initialise but do not start a server using the given configuration. */
2.85 @@ -381,11 +390,21 @@
2.86
2.87 if (config->notifications)
2.88 {
2.89 - err = ipc_server_apply_irq_for_thread(config->server, &config->irq, config->thread);
2.90 + err = ipc_server_apply_irq_for_thread(&config->irq, config->thread);
2.91
2.92 if (err)
2.93 return err;
2.94
2.95 + /* Apply auto-deletion if appropriate. */
2.96 +
2.97 + if (config->auto_deletion)
2.98 + {
2.99 + err = ipc_server_apply_deletion_for_thread(config->server, config->irq, config->thread);
2.100 +
2.101 + if (err)
2.102 + return err;
2.103 + }
2.104 +
2.105 /* Unmask the interrupt. */
2.106
2.107 ipc_init_irq(config->irq);
3.1 --- a/libnotifier/lib/src/notifier.cc Wed Mar 22 16:15:04 2023 +0100
3.2 +++ b/libnotifier/lib/src/notifier.cc Wed Mar 22 17:31:05 2023 +0100
3.3 @@ -103,7 +103,7 @@
3.4
3.5 NotifierResource *notifier = new NotifierResource;
3.6 ResourceServer server(notifier);
3.7 - long err = server.start_thread(false);
3.8 + long err = server.start_thread(true, false);
3.9
3.10 if (err)
3.11 return err;
3.12 @@ -152,7 +152,7 @@
3.13
3.14 NotifierResource *resource = new NotifierResource(this, object);
3.15 ResourceServer server(resource);
3.16 - long err = server.start_in_thread(_configs.front()->thread, false);
3.17 + long err = server.start_in_thread(_configs.front()->thread);
3.18
3.19 if (err)
3.20 return err;
4.1 --- a/libresource/include/resource/resource_server.h Wed Mar 22 16:15:04 2023 +0100
4.2 +++ b/libresource/include/resource/resource_server.h Wed Mar 22 17:31:05 2023 +0100
4.3 @@ -55,11 +55,12 @@
4.4
4.5 long start(bool finalisation = false);
4.6
4.7 - long start_in_thread(l4_cap_idx_t thread, bool finalisation = false);
4.8 + long start_in_thread(l4_cap_idx_t thread);
4.9
4.10 - long start_thread(bool finalisation = true);
4.11 + long start_thread(bool finalisation = true, bool auto_deletion = true);
4.12
4.13 - long start_thread(l4_cap_idx_t *server, bool finalisation = true);
4.14 + long start_thread(l4_cap_idx_t *server, bool finalisation = true,
4.15 + bool auto_deletion = true);
4.16 };
4.17
4.18
4.19 @@ -69,8 +70,8 @@
4.20 void resource_init_config(ipc_server_config_type *config, Resource *resource);
4.21
4.22 void resource_set_config_threaded(ipc_server_config_type *config,
4.23 - l4_cap_idx_t thread, int new_thread,
4.24 - int finalisation);
4.25 + l4_cap_idx_t thread, int separate_thread,
4.26 + int finalisation, int auto_deletion);
4.27
4.28 /* Server initiation. */
4.29
5.1 --- a/libresource/lib/src/resource_server.cc Wed Mar 22 16:15:04 2023 +0100
5.2 +++ b/libresource/lib/src/resource_server.cc Wed Mar 22 17:31:05 2023 +0100
5.3 @@ -38,8 +38,8 @@
5.4 return ipc_server_bind(name, (l4_umword_t) _config, &_config->server);
5.5 }
5.6
5.7 -/* Start in the same thread indicating whether deletion notifications and
5.8 - finalisation are to be used. */
5.9 +/* Start in the same thread indicating whether the server can be finalised. If
5.10 + so, deletion notifications will be used. */
5.11
5.12 long ResourceServer::start(bool finalisation)
5.13 {
5.14 @@ -56,24 +56,26 @@
5.15 {
5.16 _config->finaliser = resource_same_thread_finaliser;
5.17 _config->notifications = 1;
5.18 + _config->auto_deletion = 1;
5.19 }
5.20
5.21 return resource_start_config(_config, _resource);
5.22 }
5.23
5.24 -/* Start serving a resource in an existing thread. */
5.25 +/* Start serving a resource in an existing thread. The resource will not be
5.26 + finalised. */
5.27
5.28 -long ResourceServer::start_in_thread(l4_cap_idx_t thread, bool finalisation)
5.29 +long ResourceServer::start_in_thread(l4_cap_idx_t thread)
5.30 {
5.31 resource_init_config(_config, _resource);
5.32 - resource_set_config_threaded(_config, thread, 1, finalisation);
5.33 + resource_set_config_threaded(_config, thread, 1, 0, 0);
5.34
5.35 return resource_start_config(_config, _resource);
5.36 }
5.37
5.38 /* Start serving a resource in a new thread. */
5.39
5.40 -long ResourceServer::start_thread(bool finalisation)
5.41 +long ResourceServer::start_thread(bool finalisation, bool auto_deletion)
5.42 {
5.43 pthread_t thread;
5.44 pthread_attr_t attr;
5.45 @@ -88,7 +90,8 @@
5.46 if (err)
5.47 return err;
5.48
5.49 - resource_set_config_threaded(_config, pthread_l4_cap(thread), 1, finalisation);
5.50 + resource_set_config_threaded(_config, pthread_l4_cap(thread), 1, finalisation,
5.51 + auto_deletion);
5.52
5.53 return resource_start_config(_config, _resource);
5.54 }
5.55 @@ -96,9 +99,10 @@
5.56 /* A convenience method starting a thread and returning the server capability
5.57 employed via the given parameter. */
5.58
5.59 -long ResourceServer::start_thread(l4_cap_idx_t *server, bool finalisation)
5.60 +long ResourceServer::start_thread(l4_cap_idx_t *server, bool finalisation,
5.61 + bool auto_deletion)
5.62 {
5.63 - long err = start_thread(finalisation);
5.64 + long err = start_thread(finalisation, auto_deletion);
5.65
5.66 if (!err)
5.67 *server = _config->server;
5.68 @@ -123,13 +127,16 @@
5.69 /* Set a configuration to be threaded. */
5.70
5.71 void resource_set_config_threaded(ipc_server_config_type *config,
5.72 - l4_cap_idx_t thread, int new_thread,
5.73 - int finalisation)
5.74 + l4_cap_idx_t thread, int separate_thread,
5.75 + int finalisation, int auto_deletion)
5.76 {
5.77 - config->finaliser = resource_thread_finaliser;
5.78 - config->config_thread = new_thread;
5.79 + if (finalisation)
5.80 + config->finaliser = resource_thread_finaliser;
5.81 +
5.82 + config->config_thread = separate_thread;
5.83 config->thread = thread;
5.84 config->notifications = finalisation;
5.85 + config->auto_deletion = auto_deletion;
5.86 }
5.87
5.88 /* Activate a resource and start a server for it. */