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