This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perlxs: Add text about dealing with locales, etc
authorKarl Williamson <khw@cpan.org>
Fri, 22 Aug 2014 04:40:42 +0000 (22:40 -0600)
committerSteve Hay <steve.m.hay@googlemail.com>
Sun, 24 Aug 2014 20:35:11 +0000 (21:35 +0100)
This pod has been totally silent about monkey wrenches that could be
thrown by XS code doing things that can affect perl.  Add a few
cautions, including some detailed information about one area where we
have been bitten: locales.

dist/ExtUtils-ParseXS/lib/perlxs.pod
pod/perllocale.pod

index 122933b..8d4132c 100644 (file)
@@ -14,6 +14,8 @@ or statically linked into perl.  The XS interface description is
 written in the XS language and is the core component of the Perl
 extension interface.
 
 written in the XS language and is the core component of the Perl
 extension interface.
 
+Before writing XS, read the L</CAVEATS> section below.
+
 An B<XSUB> forms the basic unit of the XS interface.  After compilation
 by the B<xsubpp> compiler, each XSUB amounts to a C function definition
 which will provide the glue between Perl calling conventions and C
 An B<XSUB> forms the basic unit of the XS interface.  After compilation
 by the B<xsubpp> compiler, each XSUB amounts to a C function definition
 which will provide the glue between Perl calling conventions and C
@@ -2120,6 +2122,96 @@ File C<rpctest.pl>: Perl test program for the RPC extension.
      print "time = $a\n";
      print "netconf = $netconf\n";
 
      print "time = $a\n";
      print "netconf = $netconf\n";
 
+=head1 CAVEATS
+
+XS code has full access to system calls including C library functions.
+It thus has the capability of interfering with things that the Perl core
+or other modules have set up, such as signal handlers or file handles.
+It could mess with the memory, or any number of harmful things.  Don't.
+
+Some modules have an event loop, waiting for user-input.  It is highly
+unlikely that two such modules would work adequately together in a
+single Perl application.
+
+In general, the perl interpreter views itself as the center of the
+universe as far as the Perl program goes.  XS code is viewed as a
+help-mate, to accomplish things that perl doesn't do, or doesn't do fast
+enough, but always subservient to perl.  The closer XS code adheres to
+this model, the less likely conflicts will occur.
+
+One area where there has been conflict is in regards to C locales.  (See
+L<perllocale>.)  perl, with one exception and unless told otherwise,
+sets up the underlying locale the program is running in to that passed
+into it from the environment.  As of v5.20, this underlying locale is
+completely hidden from pure perl code outside the lexical scope of
+C<S<use locale>>; except a couple of function calls in the POSIX
+module of necessity use it.  But the underlying locale, with that one
+exception is exposed to XS code, affecting all C library routines whose
+behavior is locale-dependent.   The exception is the
+L<C<LC_NUMERIC>|perllocale/Category LC_NUMERIC: Numeric Formatting>
+locale category, and the reason it is an exception is that experience
+has shown that it can be problematic for XS code, whereas we have not
+had reports of problems with the
+L<other locale categories|perllocale/WHAT IS A LOCALE>.  And the reason
+for this one category being problematic is that the character used as a
+decimal point can vary.  Many European languages use a comma, whereas
+English, and hence Perl are expecting a dot (U+002E: FULL STOP).  Many
+modules can handle only the radix character being a dot, and so perl
+attempts to make it so.  Up through Perl v5.20, the attempt was merely
+to set C<LC_NUMERIC> upon startup to the C<"C"> locale.  Any
+L<setlocale()|perllocale/The setlocale function> otherwise would change
+it; this caused some failures.  Therefore, starting in v5.22, perl tries
+to keep C<LC_NUMERIC> always set to C<"C"> for XS code.
+
+To summarize, here's what to expect and how to handle locales in XS code:
+
+=over
+
+=item Non-locale-aware XS code
+
+Keep in mind that even if you think your code is not locale-aware, it
+may call a C library function that is.  Hopefully the man page for such
+a function will indicate that dependency, but the documentation is
+imperfect.
+
+The current locale is exposed to XS code except possibly C<LC_NUMERIC>.
+There have not been reports of problems with these other categories.
+
+Up through v5.20, Perl initializes things on start-up so that
+C<LC_NUMERIC> is set to the "C" locale.  But if any code anywhere
+changes it, it will stay changed.  This means that your module can't
+count on C<LC_NUMERIC> being something in particular, and you can't
+expect floating point numbers (including version strings) to have dots
+in them.  If you don't allow for a non-dot, your code could break if
+anyone anywhere changes the locale.  For this reason, v5.22 is changing
+the behavior so that Perl tries to keep C<LC_NUMERIC> in the "C" locale
+except around the operations internally where it should be something
+else.  Misbehaving XS code will always be able to change the locale
+anyway, but the most common instance of this is checked for and
+handled.
+
+=item Locale-aware XS code
+
+If the locale from the user's environment is desired, there should be no
+need for XS code to set the locale except for C<LC_NUMERIC>, as perl has
+already set it up.  XS code should avoid changing the locale, as it can
+adversely affect other, unrelated, code and may not be thread safe.
+However, some alien libraries that may be called do set it, such as
+C<Gtk>.  This can cause problems for the perl core and other modules.
+Starting in v5.20.1, calling the function
+L<sync_locale()|perlapi/sync_locale> from XS should be sufficient to
+avoid most of these problems.  Prior to this, you need a pure Perl
+segment that does this:
+
+ POSIX::setlocale(LC_ALL, POSIX::setlocale(LC_ALL));
+
+Macros are provided for XS code to temporarily change to use the
+underlying C<LC_NUMERIC> locale when necessary.  An API is being
+developed for this, but has not yet been nailed down, but will be during
+the course of v5.21.  Send email to L<mailto:perl5-porters@perl.org> for
+guidance.
+
+=back
 
 =head1 XS VERSION
 
 
 =head1 XS VERSION
 
index a5d776a..e086b6e 100644 (file)
@@ -211,17 +211,7 @@ locale isn't exposed to Perl space.
 
 XS modules for all categories but C<LC_NUMERIC> get the underlying
 locale, and hence any C library functions they call will use that
 
 XS modules for all categories but C<LC_NUMERIC> get the underlying
 locale, and hence any C library functions they call will use that
-underlying locale.
-
-Perl tries to keep C<LC_NUMERIC> set to C<"C">
-because too many modules are unable to cope with the decimal point in a
-floating point number not being a dot (it's a comma in many locales).
-Macros are provided for XS code to temporarily change to use the
-underlying locale when necessary; however buggy code that fails to
-restore when done can break other XS code (but not Perl code) in this
-regard.  The API for these macros has not yet been nailed down, but will be
-during the course of v5.21.  Send email to
-L<mailto:perl5-porters@perl.org> for guidance.
+underlying locale.  For more discussion, see L<perlxs/CAVEATS>.
 
 =back
 
 
 =back