From: Jan Maria Matejka Date: Fri, 14 Sep 2018 12:17:25 +0000 (+0200) Subject: Conf: Yielding from cf_read X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4cf2818c9864815cbdea93668c98f9781397b771;p=thirdparty%2Fbird.git Conf: Yielding from cf_read --- diff --git a/conf/conf.c b/conf/conf.c index 99d98c280..2316ad7ae 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -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); } /** diff --git a/conf/conf.h b/conf/conf.h index 038ef0e77..83fe78cdb 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -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); diff --git a/sysdep/unix/conf.c b/sysdep/unix/conf.c index 785044734..a19287e2b 100644 --- a/sysdep/unix/conf.c +++ b/sysdep/unix/conf.c @@ -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; }