diff options
-rw-r--r-- | pod/perlembed.pod | 2 | ||||
-rw-r--r-- | pod/perlxs.pod | 17 | ||||
-rw-r--r-- | reentr.pl | 28 |
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. @@ -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"; } } |