1*5759b3d2Safresh1################################################################################ 2*5759b3d2Safresh1## 3*5759b3d2Safresh1## Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz. 4*5759b3d2Safresh1## Version 2.x, Copyright (C) 2001, Paul Marquess. 5*5759b3d2Safresh1## Version 1.x, Copyright (C) 1999, Kenneth Albanowski. 6*5759b3d2Safresh1## 7*5759b3d2Safresh1## This program is free software; you can redistribute it and/or 8*5759b3d2Safresh1## modify it under the same terms as Perl itself. 9*5759b3d2Safresh1## 10*5759b3d2Safresh1################################################################################ 11*5759b3d2Safresh1 12*5759b3d2Safresh1=provides 13*5759b3d2Safresh1 14*5759b3d2Safresh1START_MY_CXT 15*5759b3d2Safresh1dMY_CXT_SV 16*5759b3d2Safresh1dMY_CXT 17*5759b3d2Safresh1MY_CXT_INIT 18*5759b3d2Safresh1MY_CXT_CLONE 19*5759b3d2Safresh1MY_CXT 20*5759b3d2Safresh1pMY_CXT 21*5759b3d2Safresh1pMY_CXT_ 22*5759b3d2Safresh1_pMY_CXT 23*5759b3d2Safresh1aMY_CXT 24*5759b3d2Safresh1aMY_CXT_ 25*5759b3d2Safresh1_aMY_CXT 26*5759b3d2Safresh1 27*5759b3d2Safresh1=implementation 28*5759b3d2Safresh1 29*5759b3d2Safresh1/* 30*5759b3d2Safresh1 * Boilerplate macros for initializing and accessing interpreter-local 31*5759b3d2Safresh1 * data from C. All statics in extensions should be reworked to use 32*5759b3d2Safresh1 * this, if you want to make the extension thread-safe. See ext/re/re.xs 33*5759b3d2Safresh1 * for an example of the use of these macros. 34*5759b3d2Safresh1 * 35*5759b3d2Safresh1 * Code that uses these macros is responsible for the following: 36*5759b3d2Safresh1 * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" 37*5759b3d2Safresh1 * 2. Declare a typedef named my_cxt_t that is a structure that contains 38*5759b3d2Safresh1 * all the data that needs to be interpreter-local. 39*5759b3d2Safresh1 * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. 40*5759b3d2Safresh1 * 4. Use the MY_CXT_INIT macro such that it is called exactly once 41*5759b3d2Safresh1 * (typically put in the BOOT: section). 42*5759b3d2Safresh1 * 5. Use the members of the my_cxt_t structure everywhere as 43*5759b3d2Safresh1 * MY_CXT.member. 44*5759b3d2Safresh1 * 6. Use the dMY_CXT macro (a declaration) in all the functions that 45*5759b3d2Safresh1 * access MY_CXT. 46*5759b3d2Safresh1 */ 47*5759b3d2Safresh1 48*5759b3d2Safresh1#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ 49*5759b3d2Safresh1 defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) 50*5759b3d2Safresh1 51*5759b3d2Safresh1#ifndef START_MY_CXT 52*5759b3d2Safresh1 53*5759b3d2Safresh1/* This must appear in all extensions that define a my_cxt_t structure, 54*5759b3d2Safresh1 * right after the definition (i.e. at file scope). The non-threads 55*5759b3d2Safresh1 * case below uses it to declare the data as static. */ 56*5759b3d2Safresh1#define START_MY_CXT 57*5759b3d2Safresh1 58*5759b3d2Safresh1#if { VERSION < 5.004_68 } 59*5759b3d2Safresh1/* Fetches the SV that keeps the per-interpreter data. */ 60*5759b3d2Safresh1#define dMY_CXT_SV \ 61*5759b3d2Safresh1 SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE) 62*5759b3d2Safresh1#else /* >= perl5.004_68 */ 63*5759b3d2Safresh1#define dMY_CXT_SV \ 64*5759b3d2Safresh1 SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ 65*5759b3d2Safresh1 sizeof(MY_CXT_KEY)-1, TRUE) 66*5759b3d2Safresh1#endif /* < perl5.004_68 */ 67*5759b3d2Safresh1 68*5759b3d2Safresh1/* This declaration should be used within all functions that use the 69*5759b3d2Safresh1 * interpreter-local data. */ 70*5759b3d2Safresh1#define dMY_CXT \ 71*5759b3d2Safresh1 dMY_CXT_SV; \ 72*5759b3d2Safresh1 my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv)) 73*5759b3d2Safresh1 74*5759b3d2Safresh1/* Creates and zeroes the per-interpreter data. 75*5759b3d2Safresh1 * (We allocate my_cxtp in a Perl SV so that it will be released when 76*5759b3d2Safresh1 * the interpreter goes away.) */ 77*5759b3d2Safresh1#define MY_CXT_INIT \ 78*5759b3d2Safresh1 dMY_CXT_SV; \ 79*5759b3d2Safresh1 /* newSV() allocates one more than needed */ \ 80*5759b3d2Safresh1 my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ 81*5759b3d2Safresh1 Zero(my_cxtp, 1, my_cxt_t); \ 82*5759b3d2Safresh1 sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) 83*5759b3d2Safresh1 84*5759b3d2Safresh1/* This macro must be used to access members of the my_cxt_t structure. 85*5759b3d2Safresh1 * e.g. MYCXT.some_data */ 86*5759b3d2Safresh1#define MY_CXT (*my_cxtp) 87*5759b3d2Safresh1 88*5759b3d2Safresh1/* Judicious use of these macros can reduce the number of times dMY_CXT 89*5759b3d2Safresh1 * is used. Use is similar to pTHX, aTHX etc. */ 90*5759b3d2Safresh1#define pMY_CXT my_cxt_t *my_cxtp 91*5759b3d2Safresh1#define pMY_CXT_ pMY_CXT, 92*5759b3d2Safresh1#define _pMY_CXT ,pMY_CXT 93*5759b3d2Safresh1#define aMY_CXT my_cxtp 94*5759b3d2Safresh1#define aMY_CXT_ aMY_CXT, 95*5759b3d2Safresh1#define _aMY_CXT ,aMY_CXT 96*5759b3d2Safresh1 97*5759b3d2Safresh1#endif /* START_MY_CXT */ 98*5759b3d2Safresh1 99*5759b3d2Safresh1#ifndef MY_CXT_CLONE 100*5759b3d2Safresh1/* Clones the per-interpreter data. */ 101*5759b3d2Safresh1#define MY_CXT_CLONE \ 102*5759b3d2Safresh1 dMY_CXT_SV; \ 103*5759b3d2Safresh1 my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ 104*5759b3d2Safresh1 Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\ 105*5759b3d2Safresh1 sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) 106*5759b3d2Safresh1#endif 107*5759b3d2Safresh1 108*5759b3d2Safresh1#else /* single interpreter */ 109*5759b3d2Safresh1 110*5759b3d2Safresh1#ifndef START_MY_CXT 111*5759b3d2Safresh1 112*5759b3d2Safresh1#define START_MY_CXT static my_cxt_t my_cxt; 113*5759b3d2Safresh1#define dMY_CXT_SV dNOOP 114*5759b3d2Safresh1#define dMY_CXT dNOOP 115*5759b3d2Safresh1#define MY_CXT_INIT NOOP 116*5759b3d2Safresh1#define MY_CXT my_cxt 117*5759b3d2Safresh1 118*5759b3d2Safresh1#define pMY_CXT void 119*5759b3d2Safresh1#define pMY_CXT_ 120*5759b3d2Safresh1#define _pMY_CXT 121*5759b3d2Safresh1#define aMY_CXT 122*5759b3d2Safresh1#define aMY_CXT_ 123*5759b3d2Safresh1#define _aMY_CXT 124*5759b3d2Safresh1 125*5759b3d2Safresh1#endif /* START_MY_CXT */ 126*5759b3d2Safresh1 127*5759b3d2Safresh1#ifndef MY_CXT_CLONE 128*5759b3d2Safresh1#define MY_CXT_CLONE NOOP 129*5759b3d2Safresh1#endif 130*5759b3d2Safresh1 131*5759b3d2Safresh1#endif 132*5759b3d2Safresh1 133*5759b3d2Safresh1=xsmisc 134*5759b3d2Safresh1 135*5759b3d2Safresh1#define MY_CXT_KEY "Devel::PPPort::_guts" XS_VERSION 136*5759b3d2Safresh1 137*5759b3d2Safresh1typedef struct { 138*5759b3d2Safresh1 /* Put Global Data in here */ 139*5759b3d2Safresh1 int dummy; 140*5759b3d2Safresh1} my_cxt_t; 141*5759b3d2Safresh1 142*5759b3d2Safresh1START_MY_CXT 143*5759b3d2Safresh1 144*5759b3d2Safresh1=xsboot 145*5759b3d2Safresh1 146*5759b3d2Safresh1{ 147*5759b3d2Safresh1 MY_CXT_INIT; 148*5759b3d2Safresh1 /* If any of the fields in the my_cxt_t struct need 149*5759b3d2Safresh1 * to be initialised, do it here. 150*5759b3d2Safresh1 */ 151*5759b3d2Safresh1 MY_CXT.dummy = 42; 152*5759b3d2Safresh1} 153*5759b3d2Safresh1 154*5759b3d2Safresh1=xsubs 155*5759b3d2Safresh1 156*5759b3d2Safresh1int 157*5759b3d2Safresh1MY_CXT_1() 158*5759b3d2Safresh1 CODE: 159*5759b3d2Safresh1 dMY_CXT; 160*5759b3d2Safresh1 RETVAL = MY_CXT.dummy == 42; 161*5759b3d2Safresh1 ++MY_CXT.dummy; 162*5759b3d2Safresh1 OUTPUT: 163*5759b3d2Safresh1 RETVAL 164*5759b3d2Safresh1 165*5759b3d2Safresh1int 166*5759b3d2Safresh1MY_CXT_2() 167*5759b3d2Safresh1 CODE: 168*5759b3d2Safresh1 dMY_CXT; 169*5759b3d2Safresh1 RETVAL = MY_CXT.dummy == 43; 170*5759b3d2Safresh1 OUTPUT: 171*5759b3d2Safresh1 RETVAL 172*5759b3d2Safresh1 173*5759b3d2Safresh1int 174*5759b3d2Safresh1MY_CXT_CLONE() 175*5759b3d2Safresh1 CODE: 176*5759b3d2Safresh1 MY_CXT_CLONE; 177*5759b3d2Safresh1 RETVAL = 42; 178*5759b3d2Safresh1 OUTPUT: 179*5759b3d2Safresh1 RETVAL 180*5759b3d2Safresh1 181*5759b3d2Safresh1=tests plan => 3 182*5759b3d2Safresh1 183*5759b3d2Safresh1ok(&Devel::PPPort::MY_CXT_1()); 184*5759b3d2Safresh1ok(&Devel::PPPort::MY_CXT_2()); 185*5759b3d2Safresh1ok(&Devel::PPPort::MY_CXT_CLONE()); 186