]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Conf: Yielding from cf_read mq-config-bg
authorJan Maria Matejka <mq@ucw.cz>
Fri, 14 Sep 2018 12:17:25 +0000 (14:17 +0200)
committerJan Maria Matejka <mq@ucw.cz>
Fri, 14 Sep 2018 12:50:49 +0000 (14:50 +0200)
conf/conf.c
conf/conf.h
sysdep/unix/conf.c

index 99d98c2802a22707fd2c776c14f33272b62ab02f..2316ad7ae326053536ad768d348191453ca0cade 100644 (file)
@@ -215,11 +215,17 @@ config_parse(struct conf_order *order)
   coro_resume(ctx->coro);
 }
 
-void config_yield(struct cf_context *ctx)
+void config_yield(struct conf_order *order)
 {
-  DBG("Conf: Yield\n");
-  ev_schedule(ctx->ev_resume);
-  DBG("Conf: Yield resumed\n");
+  if (order->flags & CO_SYNC)
+    return;
+
+  ASSERT(order->ctx);
+  ASSERT(order->ctx->ev_resume);
+  DBG("Conf %p: Yield\n", order);
+  ev_schedule(order->ctx->ev_resume);
+  coro_suspend();
+  DBG("Conf %p: Resumed\n", order);
 }
 
 /**
index 038ef0e77dc165d15044f66468fe448e63f1fd23..83fe78cdbd3a75ad60192705a86eef23910a308e 100644 (file)
@@ -104,6 +104,9 @@ void config_parse(struct conf_order *order);
 /** Callback for returning error from parser hooks */
 void cf_error(struct cf_context *, const char *msg, ...) NORET;
 
+/** Yield callable from conf_order callbacks */
+void config_yield(struct conf_order *order);
+
 void config_free(struct config *);
 int config_commit(struct config *, int type, uint timeout);
 int config_confirm(void);
index 785044734dcbcd4f325070534b174a1a3f143b28..a19287e2bee326bd5a3caa41e45d519d9c003107 100644 (file)
@@ -110,6 +110,7 @@ sysdep_commit(struct config *new, struct config *old UNUSED)
 
 #define MAX_INCLUDE_DEPTH 8
 #define UCO struct unix_conf_order *uco = (struct unix_conf_order *) co
+#define YIELD_AFTER 1048576
 
 struct unix_conf_order {
   struct conf_order co;                /* First field of struct conf_order is resource r; */
@@ -119,6 +120,7 @@ struct unix_conf_order {
   event *ev;                   /* Start event if called from CLI */
   int type;                    /* Type of reconfig */
   uint timeout;                        /* Config timeout */
+  uint bytecount;              /* Have read this number of bytes since last yield */
 };
 
 static void
@@ -150,9 +152,14 @@ static int
 unix_cf_read(struct conf_order *co, byte *dest, uint len)
 {
   UCO;
-
   ASSERT(uco->ifs->state == co->state);
 
+  if (uco->bytecount > YIELD_AFTER)
+    {
+      uco->bytecount -= YIELD_AFTER;
+      config_yield(co);
+    }
+
   if (uco->ifs->fd == -1)
     uco->ifs->fd = open(co->state->name, O_RDONLY);
 
@@ -169,6 +176,8 @@ unix_cf_read(struct conf_order *co, byte *dest, uint len)
   int l = read(uco->ifs->fd, dest, len);
   if (l < 0)
     cf_error(co->ctx, "Read error: %m");
+
+  uco->bytecount += l;
   return l;
 }