In article <[EMAIL PROTECTED]>, "Anders Johnson" <[EMAIL PROTECTED]> writes: > Yes, perhaps it's better to document this by describing the behavior in > more detail in L<perlcall/"G_KEEPERR">, and adding a pointer from > L<perlobj/"Destructors"> to it. > > However, from my point of view (of which anyone is welcome to disabuse > me) trying to fix the problem in call_sv is a dead end, because the > whole notion of multiple simultaneous outstanding errors is > fundamentally unsound. (See http://www.gotw.ca/gotw/047.htm for an > explanation as it relates to C++; allegedly the basic concepts are the > same in Perl.) That's why the proposed documentation suggests taking > measures to simply prevent it ever from happening.
But this isn't about multiple outstanding error. See the example I give below which never has multiple errors and still shows the cleanup. As far as I understood, your problem is an exception (raised inderectly through an interrupt) arriving while a destructor is running. The same thing would however for any perl code that's called through call_sv with G_EVAL and G_KEEPERR, where DESTROY is just a special (and common) case, so I still think call_sv is the proper place to fix it if that's what you decide to do. I also don't see why you want to make the setting per class. An interrupt can come in at any time, so I'd think you would want to catch ALL cases. About the "expensive code" issue, how about making the variable that turns the behaviour on or off into a magic variable, and let it get/set a (thread local?) integer. In the C code you can then check the value of that integer very fast. That way only people using the feature will see a noticable slowdown (the simple int check hopefully will not appear on the speed radar) > > In other words, if you get an "(in cleanup)" message at all, then the > perl script is broken. That's a somewhat draconian statement, but it's > the only reasonable way that I know of to manage the issue. > Mm, interesting read (even though I think the argumentation is sloppy and I don't agree with it). Notice however that perl actually enforces what is described there: A destructor can't raise an exception that goes all the way: #!/usr/bin/perl -wl sub DESTROY { die "Aargh"; } my $a = bless []; $a = undef; print "We got here and \$\@ is: $@" Which will print: We got here and $@ is: (in cleanup) Aargh at - line 3. It only looks like a double exception issue if the DESTROY happened while an exception was already propagating, but the behaviour in fact always occurs: exceptions in G_KEEPERR code don't propagate, but get accumulated in [EMAIL PROTECTED]