Change 30262 by [EMAIL PROTECTED] on 2007/02/13 18:05:20
Integrate:
[ 26522]
add tests for MY_CXT API and improve its documentation
[ 29124]
Subject: [PATCH] Change MY_CXT ref in perl.h
From: "Jerry D. Hedden" <[EMAIL PROTECTED]>
Date: Thu, 26 Oct 2006 08:35:46 -0700 (PDT)
Message-ID: <[EMAIL PROTECTED]>
Affected files ...
... //depot/maint-5.8/perl/MANIFEST#324 integrate
... //depot/maint-5.8/perl/ext/XS/APItest/APItest.pm#12 integrate
... //depot/maint-5.8/perl/ext/XS/APItest/APItest.xs#17 integrate
... //depot/maint-5.8/perl/ext/XS/APItest/t/my_cxt.t#1 branch
... //depot/maint-5.8/perl/perl.h#156 integrate
... //depot/maint-5.8/perl/pod/perlxs.pod#9 integrate
Differences ...
==== //depot/maint-5.8/perl/MANIFEST#324 (text) ====
Index: perl/MANIFEST
--- perl/MANIFEST#323~30248~ 2007-02-12 14:12:39.000000000 -0800
+++ perl/MANIFEST 2007-02-13 10:05:20.000000000 -0800
@@ -1001,6 +1001,7 @@
ext/XS/APItest/MANIFEST XS::APItest extension
ext/XS/APItest/README XS::APItest extension
ext/XS/APItest/t/call.t XS::APItest extension
+ext/XS/APItest/t/my_cxt.t XS::APItest: test MY_CXT interface
ext/XS/APItest/t/exception.t XS::APItest extension
ext/XS/APItest/t/hash.t XS::APItest extension
ext/XS/APItest/t/printf.t XS::APItest extension
==== //depot/maint-5.8/perl/ext/XS/APItest/APItest.pm#12 (text) ====
Index: perl/ext/XS/APItest/APItest.pm
--- perl/ext/XS/APItest/APItest.pm#11~30038~ 2007-01-27 10:13:24.000000000
-0800
+++ perl/ext/XS/APItest/APItest.pm 2007-02-13 10:05:20.000000000 -0800
@@ -21,6 +21,7 @@
G_KEEPERR G_NODEBUG G_METHOD
exception
mycroak strtab
+ my_cxt_getint my_cxt_getsv my_cxt_setint my_cxt_setsv
);
# from cop.h
@@ -34,7 +35,7 @@
sub G_NODEBUG() { 32 }
sub G_METHOD() { 64 }
-our $VERSION = '0.08';
+our $VERSION = '0.09';
bootstrap XS::APItest $VERSION;
==== //depot/maint-5.8/perl/ext/XS/APItest/APItest.xs#17 (text) ====
Index: perl/ext/XS/APItest/APItest.xs
--- perl/ext/XS/APItest/APItest.xs#16~30051~ 2007-01-28 13:56:48.000000000
-0800
+++ perl/ext/XS/APItest/APItest.xs 2007-02-13 10:05:20.000000000 -0800
@@ -3,6 +3,37 @@
#include "perl.h"
#include "XSUB.h"
+
+/* for my_cxt tests */
+
+#define MY_CXT_KEY "XS::APItest::_guts" XS_VERSION
+
+typedef struct {
+ int i;
+ SV *sv;
+} my_cxt_t;
+
+START_MY_CXT
+
+/* indirect functions to test the [pa]MY_CXT macros */
+int
+my_cxt_getint_p(pMY_CXT)
+{
+ return MY_CXT.i;
+}
+void
+my_cxt_setint_p(pMY_CXT_ int i)
+{
+ MY_CXT.i = i;
+}
+void
+my_cxt_setsv_p(SV* sv _pMY_CXT)
+{
+ MY_CXT.sv = sv;
+}
+
+
+
/* from exception.c */
int exception(int);
@@ -212,6 +243,19 @@
PROTOTYPES: DISABLE
+BOOT:
+{
+ MY_CXT_INIT;
+ MY_CXT.i = 99;
+ MY_CXT.sv = newSVpv("initial",0);
+}
+
+void
+CLONE(...)
+ CODE:
+ MY_CXT_CLONE;
+ MY_CXT.sv = newSVpv("initial_clone",0);
+
void
print_double(val)
double val
@@ -437,3 +481,35 @@
RETVAL = newRV_inc((SV*)PL_strtab);
OUTPUT:
RETVAL
+
+int
+my_cxt_getint()
+ CODE:
+ dMY_CXT;
+ RETVAL = my_cxt_getint_p(aMY_CXT);
+ OUTPUT:
+ RETVAL
+
+void
+my_cxt_setint(i)
+ int i;
+ CODE:
+ dMY_CXT;
+ my_cxt_setint_p(aMY_CXT_ i);
+
+void
+my_cxt_getsv()
+ PPCODE:
+ dMY_CXT;
+ EXTEND(SP, 1);
+ ST(0) = MY_CXT.sv;
+ XSRETURN(1);
+
+void
+my_cxt_setsv(sv)
+ SV *sv;
+ CODE:
+ dMY_CXT;
+ SvREFCNT_dec(MY_CXT.sv);
+ my_cxt_setsv_p(sv _aMY_CXT);
+ SvREFCNT_inc(sv);
==== //depot/maint-5.8/perl/ext/XS/APItest/t/my_cxt.t#1 (text) ====
Index: perl/ext/XS/APItest/t/my_cxt.t
--- /dev/null 2007-01-16 11:55:45.526841103 -0800
+++ perl/ext/XS/APItest/t/my_cxt.t 2007-02-13 10:05:20.000000000 -0800
@@ -0,0 +1,57 @@
+#!perl -w
+
+# test per-interpeter static data API (MY_CXT)
+# DAPM Dec 2005
+
+my $threads;
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+ push @INC, "::lib:$MacPerl::Architecture:" if $^O eq 'MacOS';
+ require Config; import Config;
+ if ($Config{'extensions'} !~ /\bXS\/APItest\b/) {
+ # Look, I'm using this fully-qualified variable more than once!
+ my $arch = $MacPerl::Architecture;
+ print "1..0 # Skip: XS::APItest was not built\n";
+ exit 0;
+ }
+ $threads = $Config{'useithreads'};
+ # must 'use threads' before 'use Test::More'
+ eval 'use threads' if $threads;
+}
+
+use warnings;
+use strict;
+
+use Test::More tests => 11;
+
+BEGIN {
+ use_ok('XS::APItest');
+};
+
+is(my_cxt_getint(), 99, "initial int value");
+is(my_cxt_getsv(), "initial", "initial SV value");
+
+my_cxt_setint(1234);
+is(my_cxt_getint(), 1234, "new int value");
+
+my_cxt_setsv("abcd");
+is(my_cxt_getsv(), "abcd", "new SV value");
+
+sub do_thread {
+ is(my_cxt_getint(), 1234, "initial int value (child)");
+ my_cxt_setint(4321);
+ is(my_cxt_getint(), 4321, "new int value (child)");
+
+ is(my_cxt_getsv(), "initial_clone", "initial sv value (child)");
+ my_cxt_setsv("dcba");
+ is(my_cxt_getsv(), "dcba", "new SV value (child)");
+}
+
+SKIP: {
+ skip "No threads", 4 unless $threads;
+ threads->new(\&do_thread)->join;
+}
+
+is(my_cxt_getint(), 1234, "int value preserved after join");
+is(my_cxt_getsv(), "abcd", "SV value preserved after join");
==== //depot/maint-5.8/perl/perl.h#156 (text) ====
Index: perl/perl.h
--- perl/perl.h#155~30260~ 2007-02-13 09:34:53.000000000 -0800
+++ perl/perl.h 2007-02-13 10:05:20.000000000 -0800
@@ -5153,8 +5153,9 @@
/*
* 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, and perlxs.pod for more.
+ * this, if you want to make the extension thread-safe. See
+ * ext/XS/APItest/APItest.xs for an example of the use of these macros,
+ * and perlxs.pod for more.
*
* Code that uses these macros is responsible for the following:
* 1. #define MY_CXT_KEY to a unique string, e.g.
==== //depot/maint-5.8/perl/pod/perlxs.pod#9 (text) ====
Index: perl/pod/perlxs.pod
--- perl/pod/perlxs.pod#8~30106~ 2007-02-03 09:15:45.000000000 -0800
+++ perl/pod/perlxs.pod 2007-02-13 10:05:20.000000000 -0800
@@ -1921,6 +1921,11 @@
else
RETVAL = newSVpv(MY_CXT.name[index - 1]);
+ void
+ CLONE(...)
+ CODE:
+ MY_CXT_CLONE;
+
B<REFERENCE>
@@ -1956,7 +1961,10 @@
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
@@ -1977,6 +1985,34 @@
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->new()>>), 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.
+
=back
=head2 Thread-aware system interfaces
End of Patch.