This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
locale.c: Move some mutex ops
authorKarl Williamson <khw@cpan.org>
Wed, 17 Jan 2018 18:07:42 +0000 (11:07 -0700)
committerKarl Williamson <khw@cpan.org>
Wed, 31 Jan 2018 05:49:03 +0000 (22:49 -0700)
A future commit will add a mutex, and create the convention that this
mutex if used in combination with the new one always be tried after the
new one is in effect, in order to prevent the possibility of deadlock.
Do it now, before the new one gets added.

This also adds some comments about the reason for this mutex.

locale.c

index d3d4021..27b5ac4 100644 (file)
--- a/locale.c
+++ b/locale.c
@@ -1450,8 +1450,6 @@ S_my_nl_langinfo(const int item, bool toggle)
      * switching back, as some systems destroy the buffer when setlocale() is
      * called */
 
-    LOCALE_LOCK;
-
     {
         DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
 
@@ -1459,16 +1457,20 @@ S_my_nl_langinfo(const int item, bool toggle)
             STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
         }
 
+        LOCALE_LOCK;    /* Prevent interference from another thread executing
+                           this code section (the only call to nl_langinfo in
+                           the core) */
+
         save_to_buffer(nl_langinfo(item), &PL_langinfo_buf,
                                           &PL_langinfo_bufsize, 0);
 
+        LOCALE_UNLOCK;
+
         if (toggle) {
             RESTORE_LC_NUMERIC();
         }
     }
 
-    LOCALE_UNLOCK;
-
 #  else /* Use nl_langinfo_l(), avoiding both a mutex and changing the locale */
 
     {
@@ -1552,11 +1554,12 @@ S_my_nl_langinfo(const int item, bool toggle)
 
             case PERL_CRNCYSTR:
 
-                LOCALE_LOCK;
-
                 /* We don't bother with localeconv_l() because any system that
                  * has it is likely to also have nl_langinfo() */
 
+                LOCALE_LOCK;    /* Prevent interference with other threads
+                                   using localeconv() */
+
                 lc = localeconv();
                 if (   ! lc
                     || ! lc->currency_symbol
@@ -1588,12 +1591,13 @@ S_my_nl_langinfo(const int item, bool toggle)
             case PERL_RADIXCHAR:
             case PERL_THOUSEP:
 
-                LOCALE_LOCK;
-
                 if (toggle) {
                     STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
                 }
 
+                LOCALE_LOCK;    /* Prevent interference with other threads
+                                   using localeconv() */
+
                 lc = localeconv();
                 if (! lc) {
                     retval = "";
@@ -1610,12 +1614,12 @@ S_my_nl_langinfo(const int item, bool toggle)
                 save_to_buffer(retval, &PL_langinfo_buf,
                                &PL_langinfo_bufsize, 0);
 
+                LOCALE_UNLOCK;
+
                 if (toggle) {
                     RESTORE_LC_NUMERIC();
                 }
 
-                LOCALE_UNLOCK;
-
                 break;
 
 #  endif