From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16130 invoked by alias); 29 Jun 2007 18:49:00 -0000 Received: (qmail 16121 invoked by uid 22791); 29 Jun 2007 18:48:59 -0000 X-Spam-Check-By: sourceware.org Received: from a.mail.sonic.net (HELO a.mail.sonic.net) (64.142.16.245) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 29 Jun 2007 18:48:56 +0000 Received: from snyder (209-204-172-156.dsl.dynamic.sonic.net [209.204.172.156]) by a.mail.sonic.net (8.13.8.Beta0-Sonic/8.13.7) with SMTP id l5TImgYU017668; Fri, 29 Jun 2007 11:48:45 -0700 Message-ID: <002701c7ba7e$29222e20$677ba8c0@sonic.net> Reply-To: "Michael Snyder" From: "Michael Snyder" To: "Joel Brobecker" , "Michael Snyder" , References: <9270.12.7.175.2.1183069663.squirrel@webmail.sonic.net> <20070628224815.GC12578@caradoc.them.org> <655C3D4066B7954481633935A40BB36F041427@ussunex02.svl.access-company.com> <20070628231153.GA14231@caradoc.them.org> <11470.12.7.175.2.1183080998.squirrel@webmail.sonic.net> <20070629113407.GA13561@caradoc.them.org> <20070629161950.GA3609@adacore.com> Subject: Re: [OB] Add cleanup, source.c Date: Fri, 29 Jun 2007 20:34:00 -0000 X-Mailer: Microsoft Outlook Express 6.00.2800.1437 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-06/txt/msg00533.txt.bz2 > > >From gdbint.texinfo: > > > > Your function should explicitly do or discard the cleanups it > > creates. Failing to do this leads to non-deterministic behavior since > > the caller will arbitrarily do or discard your functions cleanups. > > This need leads to two common cleanup styles. > > Humpf! I think I have contributed loads of patches that do not > follow this advice. I'll be careful in the future, but sometimes > it's not easy. For instance, when you have a function that has > multiple possible exit points... Yes, I don't feel right about this at all. When was this paragraph written? It took me a long time to figure out how make_cleanup worked, but it was also a long time ago, and I have been writing cleanups without explicitly invoking do_cleanup for many many years now. This is how I understand the subsystem: 1) Every invocation of make_cleanup (or variants) throws a callback onto a queue, that is guaranteed to be executed no later than the end of the command loop cycle, whether due to error or normal return. 2) When you save an "old_cleanups" pointer, eg. struct cleanups *old_cleanups = make_cleanup (stuff); it represents a watermark or bookmark in that queue. Now there are two things you can do with that watermark. a) discard_cleanups (old_cleanup) discards all the cleanups made AFTER that point (including "stuff"). b) do_cleanups invokes all the cleanups made after that point. 3) But both of those actions have always been optional, and in my understanding, only needed in special circumstances. The normal flow is to do nothing -- and the cleanups will be done by the command loop, before the next command. The whole purpose of this was to PREVENT having to look out for multiple or abnormal exits from a function, so that you didn't have to make sure you freed stuff before calling error or something. Adding a requirement to explicitly call do_cleanups would go against the original design purpose of the subsystem.