From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/8174 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: [PATCH] fix atexit when it is called from an atexit handler Date: Wed, 22 Jul 2015 21:18:16 -0400 Message-ID: <20150723011816.GT1173@brightrain.aerifal.cx> References: <20150722234406.GA382@port70.net> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: ger.gmane.org 1437614312 25041 80.91.229.3 (23 Jul 2015 01:18:32 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 23 Jul 2015 01:18:32 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-8187-gllmg-musl=m.gmane.org@lists.openwall.com Thu Jul 23 03:18:32 2015 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1ZI59c-00056G-4d for gllmg-musl@m.gmane.org; Thu, 23 Jul 2015 03:18:32 +0200 Original-Received: (qmail 20401 invoked by uid 550); 23 Jul 2015 01:18:30 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 20376 invoked from network); 23 Jul 2015 01:18:29 -0000 Content-Disposition: inline In-Reply-To: <20150722234406.GA382@port70.net> User-Agent: Mutt/1.5.21 (2010-09-15) Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:8174 Archived-At: On Thu, Jul 23, 2015 at 01:44:06AM +0200, Szabolcs Nagy wrote: > When running atexit handlers always restart iterating the list of > handlers so if new ones are registered they are called in the right > order. > > Note that the iteration changes the head pointer in an irreversible > way, this is not a problem, but may cause more allocations than > optimal when new handlers are registered during exit. > > The old code accepted atexit handlers after exit, but did not run > them. C11 seems to explicitly allow atexit to fail in this case, > but this situation can easily come up in C++ if a destructor has > local static object with a destructor so it should be handled. > --- > src/exit/atexit.c | 15 +++++++++++++-- > 1 file changed, 13 insertions(+), 2 deletions(-) > > diff --git a/src/exit/atexit.c b/src/exit/atexit.c > index be82718..a0fd8d7 100644 > --- a/src/exit/atexit.c > +++ b/src/exit/atexit.c > @@ -14,13 +14,24 @@ static struct fl > > static volatile int lock[2]; > > +static int next() > +{ > + int i; > + for (; head; head=head->next) > + for (i=COUNT-1; i>=0; i--) > + if (head->f[i]) > + return i; > + return -1; > +} > + > void __funcs_on_exit() > { > int i; > void (*func)(void *), *arg; > LOCK(lock); > - for (; head; head=head->next) for (i=COUNT-1; i>=0; i--) { > - if (!head->f[i]) continue; > + for (;;) { > + i = next(); > + if (i<0) break; > func = head->f[i]; > arg = head->a[i]; > head->f[i] = 0; I agree that this change should be made, but I don't like the particulars of the patch. It seems to increase exit handler runtime to O(n²) even in the case where no atexit is happening during exit, and it's not very elegant. I think a simpler solution would be to reset i to COUNT after calling f[i] if either (1) head has changed, or (2) i