bool_t
rpcb_gettime(host,timep)
- time_t &timep ; /* \$v{timep}=@{[$v{timep}=$arg]} */
+ time_t &timep; /* \$v{timep}=@{[$v{timep}=$arg]} */
char *host + SvOK($v{timep}) ? SvPV($arg,PL_na) : NULL;
OUTPUT:
timep
C<subtract_off>. Then one can use
#define XSINTERFACE_FUNC_BYOFFSET(ret,cv,f) \
- ((XSINTERFACE_CVT(ret,))fp[CvXSUBANY(cv).any_i32])
+ ((XSINTERFACE_CVT_ANON(ret))fp[CvXSUBANY(cv).any_i32])
#define XSINTERFACE_FUNC_BYOFFSET_set(cv,f) \
CvXSUBANY(cv).any_i32 = CAT2( f, _off )
dMY_CXT;
CODE:
if (MY_CXT.count >= 3) {
- warn("Already have 3 blind mice") ;
+ warn("Already have 3 blind mice");
RETVAL = 0;
}
else {
else
RETVAL = newSVpv(MY_CXT.name[index - 1]);
+ void
+ CLONE(...)
+ CODE:
+ MY_CXT_CLONE;
B<REFERENCE>
The MY_CXT_INIT macro initialises storage for the C<my_cxt_t> struct.
-It I<must> be called exactly once -- typically in a BOOT: section.
+It I<must> be called exactly once -- typically in a BOOT: section. If you
+are maintaining multiple interpreters, it should be called once in each
+interpreter instance, except for interpreters cloned from existing ones.
+(But see C<MY_CXT_CLONE> below.)
=item dMY_CXT
dMY_CXT;
MY_CXT.index = 2;
+=item aMY_CXT/pMY_CXT
+
+C<dMY_CXT> may be quite expensive to calculate, and to avoid the overhead
+of invoking it in each function it is possible to pass the declaration
+onto other functions using the C<aMY_CXT>/C<pMY_CXT> macros, eg
+
+ void sub1() {
+ dMY_CXT;
+ MY_CXT.index = 1;
+ sub2(aMY_CXT);
+ }
+
+ void sub2(pMY_CXT) {
+ MY_CXT.index = 2;
+ }
+
+Analogously to C<pTHX>, there are equivalent forms for when the macro is the
+first or last in multiple arguments, where an underscore represents a
+comma, i.e. C<_aMY_CXT>, C<aMY_CXT_>, C<_pMY_CXT> and C<pMY_CXT_>.
+
+=item MY_CXT_CLONE
+
+By default, when a new interpreter is created as a copy of an existing one
+(eg via C<<threads->create()>>), both interpreters share the same physical
+my_cxt_t structure. Calling C<MY_CXT_CLONE> (typically via the package's
+C<CLONE()> function), causes a byte-for-byte copy of the structure to be
+taken, and any future dMY_CXT will cause the copy to be accessed instead.
+
+=item MY_CXT_INIT_INTERP(my_perl)
+
+=item dMY_CXT_INTERP(my_perl)
+
+These are versions of the macros which take an explicit interpreter as an
+argument.
+
=back
+Note that these macros will only work together within the I<same> source
+file; that is, a dMY_CTX in one source file will access a different structure
+than a dMY_CTX in another source file.
+
+=head2 Thread-aware system interfaces
+
+Starting from Perl 5.8, in C/C++ level Perl knows how to wrap
+system/library interfaces that have thread-aware versions
+(e.g. getpwent_r()) into frontend macros (e.g. getpwent()) that
+correctly handle the multithreaded interaction with the Perl
+interpreter. This will happen transparently, the only thing
+you need to do is to instantiate a Perl interpreter.
+
+This wrapping happens always when compiling Perl core source
+(PERL_CORE is defined) or the Perl core extensions (PERL_EXT is
+defined). When compiling XS code outside of Perl core the wrapping
+does not take place. Note, however, that intermixing the _r-forms
+(as Perl compiled for multithreaded operation will do) and the _r-less
+forms is neither well-defined (inconsistent results, data corruption,
+or even crashes become more likely), nor is it very portable.
+
=head1 EXAMPLES
File C<RPC.xs>: Interface to some ONC+ RPC bind library functions.