Re: [c++-pthreads] Re: FW: RE: Re: I'm Lost
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [c++-pthreads] Re: FW: RE: Re: I'm Lost



David Abrahams wrote:
Dave Butenhof <david.butenhof@xxxxxx> writes:

However when one writes a robust general-purpose facility (library) that will be used in an environment supporting cancellation, that library ought to be written to support cancellation (whether or not it actually uses cancellation on its own behalf). Such libraries are not generally tasks taken on by "casual users"; and even so while hardly ideal it's perfectly adequate to simply say "this facility isn't cancel-safe; tough luck".

"Industrial strength" libraries in the environment, for example the "language runtime" itself, whether libc or STL, ought to be cancel-safe certainly. Even at that, however, because the task can be monumental, POSIX provided "cheats" -- the list of "optional" cancellation points allow a libc developer to omit all but the most critical. A C++ standard for STL *could* provide similar "cheats" to avoid requiring full implementation of cancel-safety. And again, if the user of the library (whether the main application or another library) doesn't choose to use cancellation the point is moot.

Picking this thread up from long ago, lete me say that I'm sort-of in
agreement with the above.  I say "sort of" because Dave B's statement
fails to address the following point (hereafter known as "the
statement"), and I can't tell what side of it he'd come down on:

   Any code that is already exception-safe could be automatically
   cancel-safe depending on our definition of "cancel-safe" and the
   semantics we assign to cancellation exceptions.

In the definition of "cancel-safe" that allows the statement to be
true, cancellation is a request, and doesn't absolutely force
_anything_ to happen.  IIUC, that is the status quo anyway (nobody is
even forced to invoke a cancellation point).

The cancellation exception semantics that allow the statement to be
true are that they act like any other exception, and are not
automatically rethrown at the end of catch blocks.  This is the
question primarily in dispute, IIUC.
This has been THE most contentious issue in every C++/threads discussion I've encountered since the beginning of (pthread) time.

My preference has always been that cancellation is an exception. Period. In our initial CMA architecture, and in our exception mapping of cancellation/thread-exit onto C language exceptions in Tru64 UNIX and OpenVMS, it's possible and reasonable to finalize propagation of a cancel/exit exception. That was critical for DCE, for example, so that it could trap cancellation of an RPC server thread, bring the thread back into the server's work pool, and propagate the exception across the wire to the client.

To finalize a cancel/exit under almost any normal circumstance is simply an application error. There are many worse application errors, like infinite loops, that we can't legislate around anyway. Worrying too much that someone might finalize the exception unintentionally just seemed like wasted effort. However it's also important to keep in mind that my preferences were formed with POSIX cancellation and C language (or cross-language OS) exceptions. C++ adds a lot of exception semantics and patterns on top of that.

There have been plenty of people who argue that cancel "can't" be caught; and some of these arguments trace back to the ubiquity of catch(...), especially in constructors; and they have some legitimate concerns about common C++ language patterns that might pretty much prevent a cancel from ever doing what a cancel should do.

There likely is no perfect solution.
IMO, it is worth making cancellation exceptions like any other in
order to make the statement true.  It's also worthwhile to avoid
complicating the mental model programmers must use to think about
exception handling, which, believe me, is hard enough even for many
developers of general purpose libraries to grasp (how long did it take
Dinkumware to make their STL exception-safe?)  Finally, and this may
be counterintuitive at first,

  making cancellation stoppable by catch(...) like everything else is
  sometimes **required** in order to ensure that cancellation
  propagates all the way through the stack and terminates a thread as
  expected without crashing the program.  So those who want
  cancellation to act more like an absolute guarantee of thread
  termination should support it.

For example, I write a C++ library for interfacing with Python.
Python is written in portable 'C' with no special treatment of
cancellation exceptions or the kinds of cleanups POSIX uses to do the
same thing in 'C'.  If I let any sort of C/C++-level exception
propagate into Python, its expectations are violated and will most
likely crash.  It's very common to have a layer of Python sandwiched
between C++ calls on the stack.  I can get proper cancellation
semantics by stopping cancellation exceptions at the boundary and
translating them into Python exceptions.  They'll propagate through
Python, and reach an exception translator on the other side that turns
them back into C++ exceptions.
The catch lies in whether (and how far) you'll trust application developers to do the re-throw properly. If we don't clean up all frames and eventually re-throw the cancel/exit to the runtime's base frame to terminate the thread, then we don't have cancellation. On the other hand, if we prevent a catch or force a re-throw, we lose a lot of C++ (particularly in constructors).

Part of the reason that you "can't tell what side of it [I'd] come down on" is that I've long recognized this as an essentially religious rather than technical argument. You'll come down on the side of the semantics toward which you feel the strongest emotional attachment. While I'm happy to express my experience and even preferences, I also recognize that "the other side" has some equally strong arguments and expectations, and they (well, most of them!) are not "wrong".

Someone needs to propose and champion "the great exception compromise"; but if that's to be me I don't yet have the faintest germ of a notion what it might be. So I sure hope it's going to be someone else. ;-)

begin:vcard
fn:Dave Butenhof
n:Butenhof;Dave
org:Hewlett-Packard Company;Manageability Systems Lab
adr;dom:110 Spit Brook Rd;;ZKO2-3/Q18;Nashua;NH;03062
email;internet:david.butenhof@xxxxxx
title:HP Utility Pricing software agent Technical Lead
tel;work:603.884.7460
note;quoted-printable:POSIX thread standards consultant=0D=0A=
	Author of "Programming With POSIX Threads" (Addison-Wesley)=0D=0A=
	Father to Amy (12) and Alyssa (8)
x-mozilla-html:TRUE
version:2.1
end:vcard