X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FThread-Cleanup.git;a=blobdiff_plain;f=Cleanup.xs;h=4fd00ecb41ee67c1ddb1da76baa34f595698b6a6;hp=34296e1d22116b68b21ade2426941dc496510255;hb=HEAD;hpb=15b9171b2fc61b12e0dcc123369fc2b66fe87012 diff --git a/Cleanup.xs b/Cleanup.xs index 34296e1..4fd00ec 100644 --- a/Cleanup.xs +++ b/Cleanup.xs @@ -1,45 +1,56 @@ -/* This file is part of the Scope::Upper Perl module. - * See http://search.cpan.org/dist/Scope-Upper/ */ - +/* This file is part of the Thread::Cleanup Perl module. + * See http://search.cpan.org/dist/Thread-Cleanup/ */ + #define PERL_NO_GET_CONTEXT #include "EXTERN.h" -#include "perl.h" +#include "perl.h" #include "XSUB.h" #define __PACKAGE__ "Thread::Cleanup" #define __PACKAGE_LEN__ (sizeof(__PACKAGE__)-1) -STATIC void tc_callback(pTHX_ void *); +#define TC_HAS_PERL(R, V, S) (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION >= (S)))))) STATIC void tc_callback(pTHX_ void *ud) { - int *level = ud; - SV *id; + dSP; - if (*level) { - *level = 0; - LEAVE; - SAVEDESTRUCTOR_X(tc_callback, level); - ENTER; - } else { - dSP; + ENTER; + SAVETMPS; - PerlMemShared_free(level); + PUSHMARK(SP); + PUTBACK; - ENTER; - SAVETMPS; + call_pv(__PACKAGE__ "::_CLEANUP", G_VOID | G_EVAL); - PUSHMARK(SP); - PUTBACK; + PUTBACK; - call_pv(__PACKAGE__ "::_CLEANUP", G_VOID); + FREETMPS; + LEAVE; +} - SPAGAIN; +STATIC int tc_endav_free(pTHX_ SV *sv, MAGIC *mg) { + SAVEDESTRUCTOR_X(tc_callback, NULL); - FREETMPS; - LEAVE; - } + return 0; } +STATIC MGVTBL tc_endav_vtbl = { + 0, + 0, + 0, + 0, + tc_endav_free +#if MGf_COPY + , 0 +#endif +#if MGf_DUP + , 0 +#endif +#if MGf_LOCAL + , 0 +#endif +}; + MODULE = Thread::Cleanup PACKAGE = Thread::Cleanup PROTOTYPES: DISABLE @@ -47,12 +58,16 @@ PROTOTYPES: DISABLE void CLONE(...) PREINIT: - int *level; -CODE: - { - level = PerlMemShared_malloc(sizeof *level); - *level = 1; - LEAVE; - SAVEDESTRUCTOR_X(tc_callback, level); - ENTER; + GV *gv; +PPCODE: + gv = gv_fetchpv(__PACKAGE__ "::_CLEANUP", 0, SVt_PVCV); + if (gv) { + CV *cv = GvCV(gv); + if (!PL_endav) + PL_endav = newAV(); + SvREFCNT_inc(cv); + if (!av_store(PL_endav, av_len(PL_endav) + 1, (SV *) cv)) + SvREFCNT_dec(cv); + sv_magicext((SV *) PL_endav, NULL, PERL_MAGIC_ext, &tc_endav_vtbl, NULL, 0); } + XSRETURN(0);