📄 my_cxt
字号:
#################################################################################### $Revision: 14 $## $Author: mhx $## $Date: 2007/01/02 12:32:34 +0100 $###################################################################################### Version 3.x, Copyright (C) 2004-2007, Marcus Holland-Moritz.## Version 2.x, Copyright (C) 2001, Paul Marquess.## Version 1.x, Copyright (C) 1999, Kenneth Albanowski.#### This program is free software; you can redistribute it and/or## modify it under the same terms as Perl itself.##################################################################################=providesSTART_MY_CXTdMY_CXT_SVdMY_CXTMY_CXT_INITMY_CXT_CLONEMY_CXTpMY_CXTpMY_CXT__pMY_CXTaMY_CXTaMY_CXT__aMY_CXT=implementation/* * Boilerplate macros for initializing and accessing interpreter-local * data from C. All statics in extensions should be reworked to use * this, if you want to make the extension thread-safe. See ext/re/re.xs * for an example of the use of these macros. * * Code that uses these macros is responsible for the following: * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" * 2. Declare a typedef named my_cxt_t that is a structure that contains * all the data that needs to be interpreter-local. * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. * 4. Use the MY_CXT_INIT macro such that it is called exactly once * (typically put in the BOOT: section). * 5. Use the members of the my_cxt_t structure everywhere as * MY_CXT.member. * 6. Use the dMY_CXT macro (a declaration) in all the functions that * access MY_CXT. */#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT)#ifndef START_MY_CXT/* This must appear in all extensions that define a my_cxt_t structure, * right after the definition (i.e. at file scope). The non-threads * case below uses it to declare the data as static. */#define START_MY_CXT#if { VERSION < 5.004_68 }/* Fetches the SV that keeps the per-interpreter data. */#define dMY_CXT_SV \ SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE)#else /* >= perl5.004_68 */#define dMY_CXT_SV \ SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ sizeof(MY_CXT_KEY)-1, TRUE)#endif /* < perl5.004_68 *//* This declaration should be used within all functions that use the * interpreter-local data. */#define dMY_CXT \ dMY_CXT_SV; \ my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv))/* Creates and zeroes the per-interpreter data. * (We allocate my_cxtp in a Perl SV so that it will be released when * the interpreter goes away.) */#define MY_CXT_INIT \ dMY_CXT_SV; \ /* newSV() allocates one more than needed */ \ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ Zero(my_cxtp, 1, my_cxt_t); \ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))/* This macro must be used to access members of the my_cxt_t structure. * e.g. MYCXT.some_data */#define MY_CXT (*my_cxtp)/* Judicious use of these macros can reduce the number of times dMY_CXT * is used. Use is similar to pTHX, aTHX etc. */#define pMY_CXT my_cxt_t *my_cxtp#define pMY_CXT_ pMY_CXT,#define _pMY_CXT ,pMY_CXT#define aMY_CXT my_cxtp#define aMY_CXT_ aMY_CXT,#define _aMY_CXT ,aMY_CXT#endif /* START_MY_CXT */#ifndef MY_CXT_CLONE/* Clones the per-interpreter data. */#define MY_CXT_CLONE \ dMY_CXT_SV; \ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))#endif#else /* single interpreter */#ifndef START_MY_CXT#define START_MY_CXT static my_cxt_t my_cxt;#define dMY_CXT_SV dNOOP#define dMY_CXT dNOOP#define MY_CXT_INIT NOOP#define MY_CXT my_cxt#define pMY_CXT void#define pMY_CXT_#define _pMY_CXT#define aMY_CXT#define aMY_CXT_#define _aMY_CXT#endif /* START_MY_CXT */#ifndef MY_CXT_CLONE#define MY_CXT_CLONE NOOP#endif#endif=xsmisc#define MY_CXT_KEY "Devel::PPPort::_guts" XS_VERSIONtypedef struct { /* Put Global Data in here */ int dummy;} my_cxt_t;START_MY_CXT=xsboot{ MY_CXT_INIT; /* If any of the fields in the my_cxt_t struct need * to be initialised, do it here. */ MY_CXT.dummy = 42;}=xsubsintMY_CXT_1() CODE: dMY_CXT; RETVAL = MY_CXT.dummy == 42; ++MY_CXT.dummy; OUTPUT: RETVALintMY_CXT_2() CODE: dMY_CXT; RETVAL = MY_CXT.dummy == 43; OUTPUT: RETVALintMY_CXT_CLONE() CODE: MY_CXT_CLONE; RETVAL = 42; OUTPUT: RETVAL=tests plan => 3ok(&Devel::PPPort::MY_CXT_1());ok(&Devel::PPPort::MY_CXT_2());ok(&Devel::PPPort::MY_CXT_CLONE());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -