L4Re/departure

Changeset

538:b33673595ce0
2023-03-22 Paul Boddie raw files shortlog changelog graph Separated auto-deletion from general notifications related to IPC.
libipc/include/ipc/server.h (file) libipc/lib/src/server.c (file) libnotifier/lib/src/notifier.cc (file) libresource/include/resource/resource_server.h (file) libresource/lib/src/resource_server.cc (file)
     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. */