c - Safely freeing resources in XS code (running destructors on scope exit) -


i writing xs module. allocate resource (e.g. malloc() or svrefcnt_inc()) operations involving perl api, free resource. fine in normal c because c has no exceptions, code using perl api may croak(), preventing normal cleanup , leaking resources. therefore seems impossible write correct xs code except simple cases.

when croak() myself can clean resources allocated far, may calling functions croak() directly sidestep cleanup code write.

pseudo-code illustrate concern:

static void some_other_function(pthx_ data* d) {   ...   if (perhaps) croak("could not frobnicate data"); }  module = example  package = example  void xs(uv n)   code:   {     /* allocate resources needed function */     data* object_graph;     newx(object_graph, 1, data);     data_init(object_graph, n);      /* call functions use perl api */     some_other_function(athx_ object_graph);      /* clean before returning.      * not run if above code croak()s!      * can put xs equivalent of  "try...finally" block?      */     data_destroy(object_graph);     safefree(object_graph);   } 

so how safely clean resources in xs code? how can register destructor run when exceptions thrown, or when return xs code perl code?

my ideas , findings far:

  • i can create class runs necessary cleanup in destructor, create mortal sv containing instance of class. @ point in future perl free sv , run destructor. however, seems rather backwards, , there has better way.

  • xsawyerx's xs fun booklet seems discuss destroy methods @ great length, not handling of exceptions originate within xs code.

  • leont's scope::onexit module features xs code using savedestructor() , savedestructor_x() macros. these not seem documented.

  • the perl api lists save_destructor() , save_destructor_x() functions public undocumented.

  • perl's scope.h header (included perl.h) declares savedestructor(f,p) , savedestructor_x(f,p) macros, without further explanation. judging context , scope::onexit code, f function pointer , p void pointer passed f. _x version functions declared pthx_ macro parameter.

am on right track this? should use these macros appropriate? in perl version introduced? there further guidance available on use? when precisely destructors triggered? presumably @ point related freetmps or leave macros?

upon further research, turns out savedestructor in fact documented – in perlguts rather perlapi. exact semantics documented there.

i therefore assume savedestructor supposed used "finally" block cleanup, , sufficiently safe , stable.

excerpt localizing changes in perlguts, discusses equivalent { local $foo; ... } blocks:

there way achieve similar task c via perl api: create pseudo-block, , arrange changes automatically undone @ end of it, either explicit, or via non-local exit (via die()). block-like construct created pair of enter/leave macros (see returning scalar in perlcall). such construct may created specially important localized task, or existing 1 (like boundaries of enclosing perl subroutine/block, or existing pair freeing tmps) may used. (in second case overhead of additional localization must negligible.) note xsub automatically enclosed in enter/leave pair.

inside such pseudo-block following service available:

  • […]

  • savedestructor(destructorfunc_nocontext_t f, void *p)

    at end of pseudo-block function f called argument p.

  • savedestructor_x(destructorfunc_t f, void *p)

    at end of pseudo-block function f called implicit context argument (if any), , p.

the section lists couple of specialized destructors, savefreesv(sv *sv) , savemortalizesv(sv *sv) may more correct premature sv_2mortal() in cases.

these macros have been available since forever, @ least perl 5.6 or older.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -