[293] in Pthreads mailing list archive

home help back first fref pref prev next nref lref last post

Re: pthread_cancel() and c++ destructors

daemon@ATHENA.MIT.EDU (David Brownell)
Fri Mar 15 16:59:39 1996

Date: Fri, 15 Mar 1996 11:17:19 -1000
From: David Brownell <brownell@ix.netcom.com>
To: "William S. Gribble" <grib@cs.utexas.edu>
Cc: pthreads@MIT.EDU

William S. Gribble wrote:
> 
> I notice that pthread_cancel() is not in the beta4_1 release of MIT
> pthreads.  Since I don't have the POSIX document and I can't test the
> routine, maybe someone out there can tell me what happens to local
> variables in the canceled thread: are their destructors called? 

The only implementation of MT/C++ that I _know_ has paid attention to
integrating the two properly is on Solaris 2.5, and that's what it does.
Last I checked (a year ago) nobody had done that for G++ and a pthreads
implementation such as MIT's.  (But folk were quite open to modifying
both appropriately.)

The options are basically to use the existing C++ stack unwind-protect
mechanism, or invent a new one like POSIX did in its C binding (POSIX.1c  
defined pthread_cleanup_push/pop).

That's an easy choice for a developer, since the latter means that the
built-in C++ mechanism can't _ever_ be used.  It's attuned to rationales
in the POSIX.1c group and has been run by a bunch of people on that very
committee for sanity checking.  I think that approach counts as the
"conventional wisdom":  use C++ destructors, since they're already there
to handle the cleanup tasks that exceptions(and cancellation) imply.

>	 What
> about mutexes that are held by the canceled thread?  (btw, I know about
> using a ``token holder'' or locker class to handle unexpected exits,
> I'm just wondering what happens if they aren't used)

POSIX.1c defined "cleanup handlers" to release resources as needed; the
C language doesn't have destructors/lockers/etc so they needed to invent
something new for ALL cases.  In C these look like this :

	{
		pthread_cleanup_push (handler_name, ...);
		... code goes here
		pthread_cleanup_pop (...)
	}

My memory is vague here; the parameters involve whether the handler gets
invoked in some other cases than just "cancellation cleanup".  There's a 
lexical nesting rule in POSIX.1c.  These work basically just like C++
destructors (for "auto" objects) do, except the cleanup handlers in C are
awkward and (as I recall) don't have efficient access to state on the stack.

So, if you had a complete C binding for pthreads (including cancellation)
you could presumably use the C binding for cancellation cleanup from C++,
and the main disadvantage would be that if you didn't convert ALL uses of
C++ "auto" destructors to cleanup handlers ... cancellation would do none
of the real "cleanup" that's _already_ done conventionally in destructors.
So your canceled threads would leak memory, leave inconsistent state, and
generally not behave well at all.  You've heard my conclusion about this!
-- 
David Brownell <brownell@ix.netcom.com>

home help back first fref pref prev next nref lref last post