From: Ian Jackson Date: Sat, 20 Sep 2014 16:28:56 +0000 (+0100) Subject: poll: Make handling of fds array actually dynamic X-Git-Tag: proposed.polypath.v4~56 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=secnet.git;a=commitdiff_plain;h=67be07ed798122634472d467f42727f2e92a8f40 poll: Make handling of fds array actually dynamic Previously we relied on the max_fds argument to register_for_poll being big enough and allocated an array at startup. But we are going to want to be more dynamic, so actually do the dynamic array resizing. We now start with a zero-sized array and increase it as needed. Signed-off-by: Ian Jackson --- diff --git a/secnet.c b/secnet.c index 84aac21..7a9d3f0 100644 --- a/secnet.c +++ b/secnet.c @@ -45,7 +45,6 @@ struct poll_interest { LIST_ENTRY(poll_interest) entry; }; static LIST_HEAD(, poll_interest) reg = LIST_HEAD_INITIALIZER(®); -static int32_t total_nfds=10; static bool_t finished=False; @@ -239,8 +238,6 @@ void register_for_poll(void *st, beforepoll_fn *before, i->max_nfds=max_nfds; i->nfds=0; i->desc=desc; - assert(total_nfds < INT_MAX - max_nfds); - total_nfds+=max_nfds; LIST_INSERT_HEAD(®, i, entry); return; } @@ -296,9 +293,8 @@ static void run(void) struct poll_interest *i; int rv, nfds, remain, idx; int timeout; - struct pollfd *fds; - - fds=safe_malloc(sizeof(*fds)*total_nfds, "run"); + struct pollfd *fds=0; + int allocdfds=0, shortfall=0; Message(M_NOTICE,"%s [%d]: starting\n",version,secnet_pid); @@ -319,16 +315,25 @@ static void run(void) i->after(i->state, fds+idx, i->nfds); idx+=i->nfds; } - remain=total_nfds; + if (shortfall) { + allocdfds *= 2; + allocdfds += shortfall; + fds=safe_realloc_ary(fds,sizeof(*fds),allocdfds, "run"); + } + remain=allocdfds; + shortfall=0; idx=0; timeout=-1; LIST_FOREACH(i, ®, entry) { nfds=remain; rv=i->before(i->state, fds+idx, &nfds, &timeout); if (rv!=0) { - /* XXX we need to handle this properly: increase the - nfds available */ - fatal("run: beforepoll_fn (%s) returns %d",i->desc,rv); + if (rv!=ERANGE) + fatal("run: beforepoll_fn (%s) returns %d",i->desc,rv); + assert(nfds < INT_MAX/4 - shortfall); + shortfall += nfds-remain; + nfds=0; + timeout=0; } if (timeout<-1) { fatal("run: beforepoll_fn (%s) set timeout to %d",