This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Interleaving pthread_cleanups in C and C++


Zack Weinberg <zack@codesourcery.com> writes:

> Richard Henderson <rth@redhat.com> writes:
> 
> > On Sat, May 03, 2003 at 06:08:09PM -0700, Mark Mitchell wrote:
> >> (1) pthread cancellation should be just an ordinary exception -- not
> >>     "forced unwinding".  That should be reserved for longjmp_unwind.
> > [...]
> >> I think (1) is the clear consensus position among the C++ people who
> >> have commented.
> >
> > Now that we've allowed catch-all handlers to trigger, I don't
> > believe you can tell the difference, so I don't see what it
> > really matters.
> 
> Making it a real C++ exception allows one to do things like use it
> in throw specs; catch it specifically; catch everything but it; etc.
> Basically it allows a bunch more flexibility on the C++ side of the
> fence.
> 
> > First, I very much dislike intertwining libc internals into libgcc
> > in this fashion.  I don't think I can stress this enough.
> >
> > Second, while you don't need unwind info for C only, you DO need it
> > for mixed C and C++, which is the only time you're going to care
> > about whether exceptions run C cleanups.  The reason is that if you
> > can't unwind the stack, you can't find the next C++ frame, which means
> > that you won't find the next C++ frame's catch handler.
> >
> > Third, the C sjlj has quite a bit of overhead preparing for the
> > exception even when it does not occur.  The libc people complain
> > about this every so often.  A pure libunwind solution with try/finally
> > would have no such setup overhead.
> 
> Mark's proposal IMHO goes way too far down the "anything but a
> language extension!" road; however, I am a little leery of generic
> try/finally in C, given the objections raised way back when, and
> besides which it isn't clear to me that try/finally are really what is
> wanted.  It seems to me that the appropriate extension is a subset of
> C++'s destructor functionality, allowing one to write something like
> this:
> 
> typedef void (*__pthread_cleanup_handler) (void *);
> 
> struct __pthread_cleanup {
>   __pthread_cleanup_handler handler;
>   void *arg;
>   bool execute;
> 
>   ~__pthread_cleanup() { if (execute) handler(arg); }
> };
> 
> #define pthread_cleanup_push(H, A) \
>  { struct __pthread_cleanup __pc = { (H), (A), true };
> 
> #define pthread_cleanup_pop(E) \
>   __pc.execute = E; }

Perhaps even

#define pthread_cleanup_push(H, A) \
 { struct __pthread_cleanup __pc = { (H), (A), true } \
          __attribute__((cleanup (__pthread_cleanup_routine)));

void __pthread_cleanup_routine (struct __pthread_cleanup *s)
{
  if (s->execute)
    (s->handler) (s->arg);
}

that way you don't need any tricky syntax extensions.

-- 
- Geoffrey Keating <geoffk@geoffk.org>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]