Discussion:
croaking without leaking resources
(too old to reply)
Vaclav Barta
2006-05-01 06:06:44 UTC
Permalink
Hi,

seems rather quiet in here - anybody listening? Anyway, I've written an XS
module for perl 5.8.7 (Regexp::Compare, on CPAN) using regular expressions.
It compiles them (from caller-supplied strings) with pregcomp, and I gather
the compiled regexps should be released with pregfree. That works, but I'm
concerned about invalid values. For some inputs (i.e. '[a'), pregcomp croaks
and control returns to the perl caller, which is fine, except my function
compiles *two* regexps and when the second one croaks, it doesn't get a
chance to release the first... Is there some equivalent of try/catch in XS,
or a way to register the compiled regexp as a Perl object, to be released
automatically when not needed?

Bye
Vasek
Nick Ing-Simmons
2006-05-01 08:34:21 UTC
Permalink
Post by Vaclav Barta
Hi,
seems rather quiet in here - anybody listening? Anyway, I've written an XS
module for perl 5.8.7 (Regexp::Compare, on CPAN) using regular expressions.
It compiles them (from caller-supplied strings) with pregcomp, and I gather
the compiled regexps should be released with pregfree. That works, but I'm
concerned about invalid values. For some inputs (i.e. '[a'), pregcomp croaks
and control returns to the perl caller, which is fine, except my function
compiles *two* regexps and when the second one croaks, it doesn't get a
chance to release the first... Is there some equivalent of try/catch in XS,
or a way to register the compiled regexp as a Perl object, to be released
automatically when not needed?
try/catch (i.e. eval {} in perl speak) is a little tricky to do from pure XS.
I usually call (a trivial) perl sub and use G_EVAL on the call.

So Nick C's suggestion (to another question) of using SAVEDESTRUCTOR_X
is probably the easiest.

ENTER;
SAVEDESTRUCTOR_X(your_cleanup_func, pointer_to_thing);
...
risky_stuff();
LEAVE
Post by Vaclav Barta
Bye
Vasek
Vaclav Barta
2006-05-01 07:26:28 UTC
Permalink
Post by Nick Ing-Simmons
the second one croaks, it doesn't get a chance to release the first... Is
there some equivalent of try/catch in XS, or a way to register the
compiled regexp as a Perl object, to be released automatically when not
needed?
try/catch (i.e. eval {} in perl speak) is a little tricky to do from pure
XS. I usually call (a trivial) perl sub and use G_EVAL on the call.
So Nick C's suggestion (to another question) of using SAVEDESTRUCTOR_X
is probably the easiest.
ENTER;
SAVEDESTRUCTOR_X(your_cleanup_func, pointer_to_thing);
...
risky_stuff();
LEAVE
Yes, that's it - thanks. I suppose there's no harm in using just
SAVEDESTRUCTOR - I don't need the "context" to call pregfree (I
think :-) )...

Bye
Vasek
Nick Ing-Simmons
2006-05-05 17:16:32 UTC
Permalink
Post by Vaclav Barta
Post by Nick Ing-Simmons
the second one croaks, it doesn't get a chance to release the first... Is
there some equivalent of try/catch in XS, or a way to register the
compiled regexp as a Perl object, to be released automatically when not
needed?
try/catch (i.e. eval {} in perl speak) is a little tricky to do from pure
XS. I usually call (a trivial) perl sub and use G_EVAL on the call.
So Nick C's suggestion (to another question) of using SAVEDESTRUCTOR_X
is probably the easiest.
ENTER;
SAVEDESTRUCTOR_X(your_cleanup_func, pointer_to_thing);
...
risky_stuff();
LEAVE
Yes, that's it - thanks. I suppose there's no harm in using just
SAVEDESTRUCTOR - I don't need the "context" to call pregfree (I
think :-) )...
What I would do in such a case is use pointer_to_thing to the
struct regexp * to be free-d.
Post by Vaclav Barta
Bye
Vasek
Marcus Holland-Moritz
2006-05-02 16:19:38 UTC
Permalink
Post by Nick Ing-Simmons
Post by Vaclav Barta
Hi,
seems rather quiet in here - anybody listening? Anyway, I've written an XS
module for perl 5.8.7 (Regexp::Compare, on CPAN) using regular expressions.
It compiles them (from caller-supplied strings) with pregcomp, and I gather
the compiled regexps should be released with pregfree. That works, but I'm
concerned about invalid values. For some inputs (i.e. '[a'), pregcomp croaks
and control returns to the perl caller, which is fine, except my function
compiles *two* regexps and when the second one croaks, it doesn't get a
chance to release the first... Is there some equivalent of try/catch in XS,
or a way to register the compiled regexp as a Perl object, to be released
automatically when not needed?
try/catch (i.e. eval {} in perl speak) is a little tricky to do from pure XS.
I usually call (a trivial) perl sub and use G_EVAL on the call.
There's a way to do try/catch (under certain circumstances) in XS.
If you use a recent ppport.h, it's even portable back to perl 5.003:

XCPT_TRY_START
{
risky_stuff();
}
XCPT_TRY_END

XCPT_CATCH
{
/* cleanup things here */

XCPT_RETHROW;
}

The only limitation is that you _have to_ rethrow the exception in
the catch block, i.e. you cannot catch an exception and just ignore
it. This is documented in the perlguts and perlapi manpages.

Marcus
--
With your bare hands?!?
Nick Ing-Simmons
2006-05-05 17:23:31 UTC
Permalink
Post by Marcus Holland-Moritz
Post by Nick Ing-Simmons
try/catch (i.e. eval {} in perl speak) is a little tricky to do from pure XS.
I usually call (a trivial) perl sub and use G_EVAL on the call.
There's a way to do try/catch (under certain circumstances) in XS.
XCPT_TRY_START
{
risky_stuff();
}
XCPT_TRY_END
XCPT_CATCH
{
/* cleanup things here */
XCPT_RETHROW;
}
Thanks, I had forgotten that had been put into ppport.h
This is almost certainly better than G_EVAL-ing a perl sub.
But this and call scheme are probably overkill if all you want
to do is cleanup on exit from scope.
I now recall that you can

callsv(an_xsub,G_EVAL)

which avoids having to have a trivial perl function.
Post by Marcus Holland-Moritz
The only limitation is that you _have to_ rethrow the exception in
the catch block, i.e. you cannot catch an exception and just ignore
it. This is documented in the perlguts and perlapi manpages.
And as I wanted to ignore (some) cases that explains why I have
never used it and hence forgot about it.

Continue reading on narkive:
Loading...