summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pod/perlembed.pod2
-rw-r--r--pod/perlxs.pod17
-rw-r--r--reentr.pl28
3 files changed, 44 insertions, 3 deletions
diff --git a/pod/perlembed.pod b/pod/perlembed.pod
index 9523e1f5ab..41028f879e 100644
--- a/pod/perlembed.pod
+++ b/pod/perlembed.pod
@@ -915,6 +915,8 @@ C<-Dusemultiplicity> option otherwise some interpreter variables may
not be initialized correctly between consecutive runs and your
application may crash.
+See also L<perlxs/Thread-aware system interfaces>.
+
Using C<-Dusethreads -Duseithreads> rather than C<-Dusemultiplicity>
is more appropriate if you intend to run multiple interpreters
concurrently in different threads, because it enables support for
diff --git a/pod/perlxs.pod b/pod/perlxs.pod
index e6f1862e56..6d14bae275 100644
--- a/pod/perlxs.pod
+++ b/pod/perlxs.pod
@@ -2025,6 +2025,23 @@ 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.
diff --git a/reentr.pl b/reentr.pl
index 13cf4d1087..9edc7ade26 100644
--- a/reentr.pl
+++ b/reentr.pl
@@ -61,13 +61,29 @@ print <<EOF;
#ifndef REENTR_H
#define REENTR_H
+/* If compiling for a threaded perl, we will macro-wrap the system/library
+ * interfaces (e.g. getpwent()) which have threaded versions
+ * (e.g. getpwent_r()), which will handle things correctly for
+ * the Perl interpreter, but otherwise (for XS) the wrapping does
+ * not take place. See L<perlxs/Thread-aware system interfaces>.
+ */
+
+#ifndef PERL_REENTR_API
+# if defined(PERL_CORE) || defined(PERL_EXT)
+# define PERL_REENTR_API 1
+# else
+# define PERL_REENTR_API 0
+# endif
+#endif
+
#ifdef USE_REENTRANT_API
/* Deprecations: some platforms have the said reentrant interfaces
* but they are declared obsolete and are not to be used. Often this
* means that the platform has threadsafed the interfaces (hopefully).
* All this is OS version dependent, so we are of course fooling ourselves.
- * If you know of more deprecations on some platforms, please add your own. */
+ * If you know of more deprecations on some platforms, please add your own
+ * (by editing reentr.pl, mind!) */
#ifdef __hpux
# undef HAS_CRYPT_R
@@ -547,7 +563,7 @@ EOF
push @size, <<EOF;
# if defined(HAS_SYSCONF) && defined($sc) && !defined(__GLIBC__)
PL_reentrant_buffer->$sz = sysconf($sc);
- if (PL_reentrant_buffer->$sz == -1)
+ if (PL_reentrant_buffer->$sz == (size_t) -1)
PL_reentrant_buffer->$sz = REENTRANTUSUALSIZE;
# else
# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
@@ -634,6 +650,7 @@ EOF
push @wrap, $ifdef;
push @wrap, <<EOF;
+# if defined(PERL_REENTR_API) && (PERL_REENTR_API == 1)
# undef $func
EOF
@@ -698,6 +715,7 @@ EOF
} split '', $b;
$w = ", $w" if length $v;
}
+
my $call = "${func}_r($v$w)";
# Must make OpenBSD happy
@@ -732,10 +750,14 @@ EOF
}
}
push @wrap, <<EOF;
-# endif
+# endif /* if defined(PERL_REENTR_API) && (PERL_REENTR_API == 1) */
EOF
}
+ push @wrap, <<EOF;
+# endif /* HAS_\U$func */
+EOF
+
push @wrap, $endif, "\n";
}
}