]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Config obstacles are lockless now
authorMaria Matejka <mq@ucw.cz>
Mon, 21 Aug 2023 13:37:09 +0000 (15:37 +0200)
committerMaria Matejka <mq@ucw.cz>
Thu, 24 Aug 2023 15:21:58 +0000 (17:21 +0200)
conf/conf.c
conf/conf.h

index c7cd81fefb886cc5dfcd80659cc14ad68c3af0ce..99927ce0b26dc6969ef49dceb8be6731f67b1ce1 100644 (file)
@@ -70,7 +70,7 @@ static int future_cftype;             /* Type of scheduled transition, may also be RECONFIG
 /* Note that when future_cftype is RECONFIG_UNDO, then future_config is NULL,
    therefore proper check for future scheduled config checks future_cftype */
 
-static event *config_event;            /* Event for finalizing reconfiguration */
+static void config_done(void *cf);
 static timer *config_timer;            /* Timer for scheduled configuration rollback */
 
 /* These are public just for cmd_show_status(), should not be accessed elsewhere */
@@ -110,6 +110,8 @@ config_alloc(const char *name)
   c->tf_base = c->tf_log = TM_ISO_LONG_MS;
   c->gr_wait = DEFAULT_GR_WAIT;
 
+  c->done_event = (event) { .hook = config_done, .data = c, };
+
   return c;
 }
 
@@ -228,16 +230,15 @@ void
 config_add_obstacle(struct config *c)
 {
   DBG("+++ adding obstacle %d\n", c->obstacle_count);
-  c->obstacle_count++;
+  atomic_fetch_add_explicit(&c->obstacle_count, 1, memory_order_acq_rel);
 }
 
 void
 config_del_obstacle(struct config *c)
 {
   DBG("+++ deleting obstacle %d\n", c->obstacle_count);
-  c->obstacle_count--;
-  if (!c->obstacle_count && (c != config))
-    ev_schedule(config_event);
+  if (atomic_fetch_sub_explicit(&c->obstacle_count, 1, memory_order_acq_rel) == 1)
+    ev_send_loop(&main_birdloop, &c->done_event);
 }
 
 static int
@@ -313,8 +314,11 @@ config_do_commit(struct config *c, int type)
 }
 
 static void
-config_done(void *unused UNUSED)
+config_done(void *cf)
 {
+  if (cf == config)
+    return;
+
   if (config->shutdown)
     sysdep_shutdown_done();
 
@@ -517,9 +521,6 @@ config_init(void)
 {
   config_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Configurations");
 
-  config_event = ev_new(config_pool);
-  config_event->hook = config_done;
-
   config_timer = tm_new(config_pool);
   config_timer->hook = config_timeout;
 }
index b30914c19517603e72abe6ba75ea8f4b0814f1ef..c51b01c9966efeed1df1561a95b20728baf3ea4b 100644 (file)
@@ -57,7 +57,8 @@ struct config {
   int thread_count;                    /* How many worker threads to prefork */
 
   struct sym_scope *root_scope;                /* Scope for root symbols */
-  int obstacle_count;                  /* Number of items blocking freeing of this config */
+  _Atomic int obstacle_count;          /* Number of items blocking freeing of this config */
+  event done_event;                    /* Called when obstacle_count reaches zero */
   int shutdown;                                /* This is a pseudo-config for daemon shutdown */
   int gr_down;                         /* This is a pseudo-config for graceful restart */
   btime load_time;                     /* When we've got this configuration */