From: Vincent Pit Date: Sat, 4 Oct 2014 15:37:25 +0000 (+0200) Subject: Don't cleanup thread local storage before END blocks are executed X-Git-Tag: v0.13~7 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2Fautovivification.git;a=commitdiff_plain;h=0c93e9f08676e6d77f7381a87e15c6dcc898683a Don't cleanup thread local storage before END blocks are executed reap.h is no longer necessary. --- diff --git a/MANIFEST b/MANIFEST index b02cf89..dba48fc 100644 --- a/MANIFEST +++ b/MANIFEST @@ -7,7 +7,6 @@ README autovivification.xs lib/autovivification.pm ptable.h -reap.h samples/bench.pl samples/hash2array.pl t/00-load.t diff --git a/autovivification.xs b/autovivification.xs index 7fc4a4e..d92b0b7 100644 --- a/autovivification.xs +++ b/autovivification.xs @@ -210,8 +210,6 @@ STATIC void a_ptable_clone(pTHX_ ptable_ent *ent, void *ud_) { #endif /* A_WORKAROUND_REQUIRE_PROPAGATION */ -#include "reap.h" - STATIC void a_thread_cleanup(pTHX_ void *ud) { dMY_CXT; @@ -221,6 +219,29 @@ STATIC void a_thread_cleanup(pTHX_ void *ud) { ptable_seen_free(MY_CXT.seen); } +STATIC int a_endav_free(pTHX_ SV *sv, MAGIC *mg) { + SAVEDESTRUCTOR_X(a_thread_cleanup, NULL); + + return 0; +} + +STATIC MGVTBL a_endav_vtbl = { + 0, + 0, + 0, + 0, + a_endav_free +#if MGf_COPY + , 0 +#endif +#if MGf_DUP + , 0 +#endif +#if MGf_LOCAL + , 0 +#endif +}; + #endif /* A_THREADSAFE */ #if A_WORKAROUND_REQUIRE_PROPAGATION @@ -1233,6 +1254,7 @@ PREINIT: ptable *t; #endif ptable *s; + GV *gv; PPCODE: { dMY_CXT; @@ -1256,7 +1278,23 @@ PPCODE: #endif MY_CXT.seen = s; } - reap(3, a_thread_cleanup, NULL); + gv = gv_fetchpv(__PACKAGE__ "::_THREAD_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, &a_endav_vtbl, NULL, 0); + } + XSRETURN(0); + +void +_THREAD_CLEANUP(...) +PROTOTYPE: DISABLE +PPCODE: + a_thread_cleanup(aTHX_ NULL); XSRETURN(0); #endif /* A_THREADSAFE */ diff --git a/reap.h b/reap.h deleted file mode 100644 index 9073899..0000000 --- a/reap.h +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of the autovivification Perl module. - * See http://search.cpan.org/dist/autovivification/ */ - -/* This header provides a specialized version of Scope::Upper::reap that can be - * called directly from XS. - * See http://search.cpan.org/dist/Scope-Upper/ for details. */ - -#ifndef REAP_H -#define REAP_H 1 - -#define REAP_DESTRUCTOR_SIZE 3 - -typedef struct { - I32 depth; - I32 *origin; - void (*cb)(pTHX_ void *); - void *ud; - char *dummy; -} reap_ud; - -STATIC void reap_pop(pTHX_ void *); - -STATIC void reap_pop(pTHX_ void *ud_) { - reap_ud *ud = ud_; - I32 depth, *origin, mark, base; - - depth = ud->depth; - origin = ud->origin; - mark = origin[depth]; - base = origin[depth - 1]; - - if (base < mark) { - PL_savestack_ix = mark; - leave_scope(base); - } - PL_savestack_ix = base; - - if ((ud->depth = --depth) > 0) { - SAVEDESTRUCTOR_X(reap_pop, ud); - } else { - void (*cb)(pTHX_ void *) = ud->cb; - void *cb_ud = ud->ud; - - PerlMemShared_free(ud->origin); - PerlMemShared_free(ud); - - SAVEDESTRUCTOR_X(cb, cb_ud); - } -} - -STATIC void reap(pTHX_ I32 depth, void (*cb)(pTHX_ void *), void *cb_ud) { -#define reap(D, CB, UD) reap(aTHX_ (D), (CB), (UD)) - reap_ud *ud; - I32 i; - - if (depth > PL_scopestack_ix) - depth = PL_scopestack_ix; - - ud = PerlMemShared_malloc(sizeof *ud); - ud->depth = depth; - ud->origin = PerlMemShared_malloc((depth + 1) * sizeof *ud->origin); - ud->cb = cb; - ud->ud = cb_ud; - ud->dummy = NULL; - - for (i = depth; i >= 1; --i) { - I32 j = PL_scopestack_ix - i; - ud->origin[depth - i] = PL_scopestack[j]; - PL_scopestack[j] += REAP_DESTRUCTOR_SIZE; - } - ud->origin[depth] = PL_savestack_ix; - - while (PL_savestack_ix + REAP_DESTRUCTOR_SIZE - <= PL_scopestack[PL_scopestack_ix - 1]) { - save_pptr(&ud->dummy); - } - - SAVEDESTRUCTOR_X(reap_pop, ud); -} - -#endif /* REAP_H */