pthread_cancel and EH: let's try this again
Alexander Terekhov
terekhov at web.de
Thu Jul 21 10:47:42 UTC 2005
Peter Dimov wrote:
>
> Alexander Terekhov wrote:
>
> > It may partially[*] solve it in the case of dtors (making dtors have
> > implicit throw()-nothing catch-less ES [ES fixed edition so to speak]
> > by default and mandating intelligent cancel delivery would solve it
> > much better and won't inhibit use of cancellation inside dtors), but
> > what about "unwinding" using catch-rethrow "dtors" that can also eat
> > exceptions?
> >
> > try {
> > operation();
> > }
> > catch(...) {
> > // End of stack unwinding
> > try {
> > cleanup();
> > }
> > catch(...) {
> > // eat exception
> > }
> > throw; // Begin of another stack unwinding
> > }
>
> The stack unwinding doesn't end when the catch block is entered. That's when
> the exception is "caught" - uncaught_exception() starts returning true - but
> it's not until the catch block ends when the exception is considered
> "finished".
Really? Read the definition. There are different try blocks. Each throw
expression starts new stack unwinding (if there are any destructors
on the path to the handler; exception specs and EH termination aside
for a moment). And, BTW, uncaught_exception() is totally busted because
in C++ there can be multiple active exceptions.
#include <iostream>
using namespace std;
int ex_count = 0;
int foo();
struct object { ~object() { foo(); } };
int foo() {
int ex = ex_count++;
try {
if (ex < 10) {
object obj;
std::cout << "throw " << ex << std::endl;
throw ex;
}
else {
std::cout << "Okay, enough active exceptions and stack unwindings." << endl;
}
}
catch(int ex_caught) {
std::cout << "caught " << ex_caught << std::endl;
}
return ex;
}
int main() {
return foo();
}
Here we've got ten try blocks, ten throw expressions, and ten "stack
unwindings".
See also
http://groups.google.de/group/comp.lang.c++.moderated/msg/4b355d902b123bf3
(exception_scope() and active_exception<T>(int))
>
> > [*] Consider:
> >
> > struct X {
> >
> > X() {
> > pthread_cancel(pthread_self());
> > }
> >
> > ~X() throw() {
> > printf("may go boom");
> > }
> >
> > };
> >
> > int main() {
> > X x;
> > }
>
> Yes, this can terminate() under most "non-intelligent" models, except the
> one where destructors disable cancellation. The cause of the termination is
> the throw() specification, though, not the destructor - you can replace ~X
> with an ordinary function. This is one of the motivating examples for the
> ECANCEL school of thought.
Yes, plus mandated stickiness. The thing is that it doesn't solve anything.
Cancel-unaware code was not designed to deal with cancel delivery in the
first place. Think of ungetc() and stuff like that. It doesn't matter what
happens afterwards or what's used as reporting mechanism. See it?
regards,
alexander.
More information about the c++-pthreads
mailing list