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.
 
+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
@@ -2120,6 +2122,96 @@ File C<rpctest.pl>: Perl test program for the RPC extension.
      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
 
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
-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