This is the mail archive of the gcc-patches@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: [basic-improvements] try/finally support for c/c++ - more tests


On the contrary, these are for cleanups that _would_ have to be run
when that "throw 3" was triggered.  It would have to be:
try {
  pthread_cleanup_push (...);
  throw 3;
  pthread_cleanup_pop (...);
} catch (...) { }

though.
I did not understand the requirement that pthread_cleanup_push and
pthread_cleanup_pop be within the same lexical scope.

It's still arguable whether or not you should be calling the cleanup
at this point.  I don't see anything in the pthreads spec that says
what happens if you do a "goto" out of the block, for example.  I agree
that, without my language lawyer hat on, doing the cleanup on any block
exit seems like a good thing.

You will, however, break code that presently does:

 try {
   pthread_cleanup_push (...);
   throw 3;
   pthread_cleanup_pop (...);
 } catch (...) {
   // Do the cleanup by hand; I know it will not have been run.
 }

Well, let's not argue that.

Our goals, then, seem to be:

(1) Make life easier for C++ programmers by calling cleanups as
    exceptions propagate.  (This can already be managed explicitly,
    with try/catch, but if we can fold it into the library, that's
    a good QOI thing.  We do have to be very careful to document it;)

(2) Shield GNU libc developers from having to write the few bits of
    the library that they want to be exception-safe in C++.

The second bit carries no weight with me at all.  It's no big deal to
write a few source files in the C++ almost-superset of C.

The first bit is, however, a good, user-focused idea.

But why not just do that at the source level?  In pthread.h:

 #ifdef __cplusplus
 #define pthread_cleanup_push(routine, arg) \
   { struct pthread_cleanup c(routine, arg);

 #define pthread_cleanup_pop(execute) \
   c.run(execute); }
 #endif

with something like:

 struct pthread_cleanup {
   pthread_cleanup (void (*r)(void*), void *a)
    : r_(r), a_(a) {}
   ~pthread_cleanup () { if (r_) r_(a); }
   void run(int execute) { if (execute) { _r(_a); } _r = 0; }
 };

I'm sure there are subtleties I got wrong, but that's the idea.

--
Mark Mitchell                mark@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com


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