Re: [c++-pthreads] Re: thread-safety definition
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [c++-pthreads] Re: thread-safety definition



Ross Smith wrote:

On Tuesday 13 January 2004 02:41, Dave Butenhof wrote:
I think I disagree, at least philsophically, with the
characterization of the model as "fragile". But I think I also
understand what you mean; and the problem isn't with the model, but
rather with the effect of that model on existing code that
all-too-casually and agressively eats exceptions it doesn't
understand. I think there are vanishingly few circumstances where a
blind catch(...) without an unconditional re-throw should be
considered "legitimate".
I'm beginning to get the same worried feeling Wil Evers expressed a few messages back. It sounds as though a lot of people are seriously considering the idea of allowing exceptions to escape from destructors.

Dave, while I have the greatest respect for your knowledge and understanding of threads, I think the above shows that you don't really understand C++.

While I wouldn't dispute the statement that "I don't really understand C++", I absolutely do understand objects, encapsulation, modularity, exceptions, cancellation, and resource ownership; and what you're saying seems essentially "obvious and self-evident". I never argued, or suggested, or assumed, that exceptions would propagate out of destructors. But I'm talking about cancel, not exceptions.

Please try to understand that it is _absolutely vital_ that destructors never be allowed to throw under any circumstances. If a destructor calls a function that may throw some unknown exception (a very common case, especially in template classes whose destructors will often call member functions of some arbitrary user-supplied type), the call _must_ be wrapped in a catch-and-discard-all block. At most you can log the error somewhere.

Any attempt to standardise a solution that doesn't take "Destructors Must Not Throw" as axiomatic is simply going to be a non-starter as far as C++ programmers are concerned. I'd really like to see this list explicitly address this issue rather than continuing to casually talk about uncatchable exceptions and similar horrors.
This discussion is a swirling mix of different issues. They're often related, but please don't assume relations where they're not stated!

Generally, any code that cannot raise (or propagate) an exception SHOULD NOT BE A CANCELLATION POINT. (Note to Dave Abrahams: Sorry, was that shout approved? ;-) )

In the context of cancellation, I don't care about whether exceptions can propagate out of destructors. As has already been said, while a destructor might be activated as part of handling and cleaning up from a cancel, that's not the same as propagating a local exception out of the destructor. If destructors are not cancellable, then no cancel exception can BEGIN within the destructor and the question of whether it could propagate out of the destructor is moot. (For what it's worth, I don't believe that they can or should.) Furthermore, a no-cancel destructor, regardless of whether it has a catch(...) with or without a re-throw, cannot possibily "eat" a cancel, because it can never catch a cancel that's not thrown within the dynamic scope of its try block.

I suspect that destructors should be implicitly "no cancel zones". (Someone expressed a concern about runtime overhead; but the cost of enabling and disabling cancel CAN be made extremely low by collusion between C++ and the thread library. That's an implementation detail the standard doesn't necessarily need to explicitly address.) There might be cases where someone really wants an indefinite blocking operation in a destructor (perhaps to disconnect from a remote server), and might want that to be cancellable. I think that's a rare special case, and could probably be handled by manually enabling cancel over that range of code, catching/finalizing the cancel if it occurs, cleaning up, restoring the original "cancel disabled" state, and then calling pthread_cancel(pthread_self()) to re-pend the cancel. Perhaps (though it seems doubtful) this might be common enough to justify some special syntax to encapsulate the mechanism and avoid errors.

--
/--------------------[ David.Butenhof@xxxxxx ]--------------------\
| Hewlett-Packard Company       Tru64 UNIX & VMS Thread Architect |
|     My book: http://www.awl.com/cseng/titles/0-201-63392-2/     |
\----[ http://homepage.mac.com/dbutenhof/Threads/Threads.html ]---/