10

The GNU C library uses DWARF2 unwinding for pthread cancellation these days, so that both C++ exceptions and pthread cancellation cleanup handlers get called through a common call frame unwinding process which invokes destructors for automatic objects as necessary along the way. However, as far as I can tell there is still no standard that specifies the interaction between (POSIX) threads and C++, and presumably an application wishing to be portable should assume that throwing exceptions out of cancellation cleanup contexts is just as undefined as calling longjmp out of them, and that cancelling a thread that has live automatic objects with non-trivial destructors is also undefined behavior.

Is there any standardization process in progress that addresses this interaction, or is it something that can be expected to be undefined well into the future? Does C++11 have any analogous notion to POSIX thread cancellation in its thread support?

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 5
    I imagine you're supposed to use `` in C++11 and not Posix... then you have exception pointers and all that to get a handle on exception propagation. – Kerrek SB Feb 25 '12 at 00:46
  • 2
    Does `` have an analogue to POSIX thread cancellation? It seems that it would be difficult to specify since the whole point of POSIX thread cancellation is the way it interacts with POSIX functions that could block forward progress of the thread for significant or unbounded amounts of time. – R.. GitHub STOP HELPING ICE Feb 25 '12 at 00:51
  • Good question; there's nothing in the standard about cancellation, and thus I assume that there's no standard mechanism for interaction with Posix threads. Do you need cancellation at all, though? If you rethink your solution in C++, is there no more idiomatic way? – Kerrek SB Feb 25 '12 at 11:34
  • @Kerrek: Actually my question was aimed at determining if there's any reason to mimic the glibc behavior in an implementation; an effort to take standards in that direction would be a good reason to consider it as a medium- to long-term goal, but putting in the large amount of effort (and significant costs to programs that don't want/need this feature) makes is otherwise undesirable, at least from my perspective. – R.. GitHub STOP HELPING ICE Feb 25 '12 at 13:37

1 Answers1

13

As someone who sits on ISO/IEC SC22 which encompasses WG14 (C), WG15 (POSIX) and WG21 (C++), I can tell you that the quick answer is no, C++ exceptions and thread cancellation are not going to see one another any time soon. C11 and C++11 make no mention of thread cancellation, and are highly if not extremely unlikely to recognise it before the next major standards release in about ten years time.

The longer answer comes down to how standards work. Basically ISO can only standardise what everyone can come to agree upon, and people do not agree when it comes to thread cancellation. The whole idea of a thread of execution having to dump state before every cancellable system call goes against the whole ethos of modern software development. It causes immense problems for compiler optimisation because unlike C++ exception throws, a thread cancel is defined to be the same as calling thread_terminate(self) which explicitly precludes doing anything additional (and even cancellation handlers aren't reliably called on many implementations), and I don't think that the thread cancellation supporters would disagree it's a bad solution.

The problem is that the only proper alternative is to reissue the POSIX i/o API with async completion variants. And the problem with that is that different POSIX implementations think of async completion very differently. I mean, we can't even agree on a standard for kernel wait queues, so until that can be achieved an async i/o API is a long way off. I have a proposal to make some movement on kernel wait queues for the next standards TC/TR, but the proposed object is deliberately extremely simplistic.

What we've tried to do in C11/C++11 is for the threading API to always have non-blocking versions - there is only one API in there which can't be done non-blocking which is thread_join() (there is no thread_timedjoin()) and I plan to personally submit an errata on that after I have Austin Working Group approval. In all other cases, one can always construct something which polls which isn't efficient, but is program correct.

In the longer run, personally speaking I see plenty of good reason to add exception handling to C following similar semantics to C++. You wouldn't have object support necessarily (I would actually support adding non-virtual objects to C too personally), but you would have the concept of stack unwound lambda function calls. That would let us formalise hacks like thread cancellation with a properly defined mechanism. It also makes writing fault tolerant C much easier and safer by letting you write the unwind as you write the wind, and lets old C transparently interop with new C.

Regarding throwing exceptions from within exception handling, me personally I think we need to do something better than just always auto invoking terminate(). As unwinding may cause the construction of new objects, or indeed any other source of exception throws, I personally would greatly prefer if every reasonable attempt is made to unwind the whole stack before terminating the process.

So, in short, expect POSIX thread cancellation to continue to be viewed as undefined, and the strong chances are in the long run it'll get deprecated in favour of something better.

BTW, generally POSIX thread cancellation is highly unportable between implementations, so any code which uses POSIX thread cancellation is effectively relying on platform-specific behaviour which is identical to using non-POSIX APIs. If you want your code to be portable, don't use POSIX thread cancellation. Instead use select() or poll() including a magic "please stop thread now" file descriptor. In my own C++ code, I actually have a system API wrapper macro which tests for this magic file descriptor and throws a special C++ exception. This ensures identical behaviour on all platforms, including Windows.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
Niall Douglas
  • 9,212
  • 2
  • 44
  • 54
  • Thanks, this was exactly the sort of answer I was looking for. – R.. GitHub STOP HELPING ICE Feb 27 '12 at 19:25
  • By the way, welcome to SO! Hope you'll continue to be part of the community. I've opened a +500 bounty to assign to your answer once the 24hr waiting period is up. – R.. GitHub STOP HELPING ICE Feb 27 '12 at 22:29
  • Thanks. To be honest up until now almost all my helping others was on mailing lists - I've chalked up something like over 10k emails to tech mailing lists according to google. But I gotta admit, google rates stackoverflow so highly in search returns versus everything else I probably have been wasting my effort! :) – Niall Douglas Feb 28 '12 at 02:09
  • I ran across SO almost 2 years ago in the middle of working on my C/POSIX library implementation, and ever since it's been the first source I go to when I have a moderately tough question. Especially with the decline in search result quality over the past few years and the abundance of fake/SEO-spam Q&A/help sites these days, SO (and other stackexchange sites) seem to be the best source for real help and good information. – R.. GitHub STOP HELPING ICE Feb 28 '12 at 02:21
  • BTW, congrats on such a great reputation in two years! For more basic topics I agree (e.g. http://stackoverflow.com/questions/92540/save-and-restore-form-position-and-size/), SO just supplies an answer which copy & paste works. However, when I scan the list of unanswered questions, many are too domain specific to expect an answer outside that particular technology's ecosystem. For those, trawling mailing list archives or being lazy and just asking for the N-th time has sadly no substitute! I wish we had a Careers 2.0 aggregator for domain tech expertise! – Niall Douglas Feb 28 '12 at 16:32
  • For reference, the issues I said I'd personally endeavour to have considered are being tracked as follows: http://www.nedproductions.biz/redmine/issues/18 (Add pthread_timedjoin() to official API) http://www.nedproductions.biz/redmine/issues/20 (Asynchronous notifier object) http://www.nedproductions.biz/redmine/issues/25 (Add C++ compatible exception handling to C, and use it to fix things like pthread cancellation). The Irish SC22 LinkedIn group can be found at http://www.linkedin.com/groups?about=&gid=4347282&trk=anet_ug_grppro – Niall Douglas Mar 12 '12 at 12:02
  • I'll just add to my own comment that I haven't had the time to do more than issues 18 and 20 before I relocate to Canada, and I have to resign from ISO standards when I leave Ireland. I guess this problem of standardising stack unwinding is going to have to live on :( – Niall Douglas Jul 20 '12 at 16:02
  • I'm quite happy to have it kept out of C, where (in my not-so-humble opinion) it does not belong. – R.. GitHub STOP HELPING ICE Jul 20 '12 at 21:09