This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add probe for nl_langinfo_l (thread-safe)
authorKarl Williamson <khw@cpan.org>
Thu, 19 Oct 2017 21:50:13 +0000 (15:50 -0600)
committerKarl Williamson <khw@cpan.org>
Thu, 19 Oct 2017 21:50:13 +0000 (15:50 -0600)
U/threads/d_nl_langinfo_l.U [new file with mode: 0644]

diff --git a/U/threads/d_nl_langinfo_l.U b/U/threads/d_nl_langinfo_l.U
new file mode 100644 (file)
index 0000000..a95760b
--- /dev/null
@@ -0,0 +1,121 @@
+?RCS: $Id$
+?RCS:
+?RCS: Copyright (c) 2017 Karl Williamson
+?RCS:
+?RCS: You may distribute under the terms of either the GNU General Public
+?RCS: License or the Artistic License, as specified in the README file.
+?RCS:
+?MAKE:d_thread_safe_nl_langinfo_l: Compile cat rm_try Oldconfig \
+       i_pthread i_stdlib i_string i_langinfo i_locale         \
+       usethreads run
+?MAKE: -pick add $@ %<
+?S:d_thread_safe_nl_langinfo_l:
+?S:    This variable contains the eventual value of the
+?S:    HAS_THREAD_SAFE_NL_LANGINFO_L symbol, which indicates if the
+?S:    nl_langinfo_l() function exists and is thread-safe.
+?S:.
+?C:HAS_THREAD_SAFE_NL_LANGINFO_L:
+?C:    This symbol, when defined, indicates presence of the nl_langinfo_l()
+?C:    function, and that it is thread-safe.
+?C:.
+?H:#$d_thread_safe_nl_langinfo_l HAS_THREAD_SAFE_NL_LANGINFO_L /**/
+?H:.
+?F:!try
+: check for thread_safe_nl_langinfo_l item
+$cat <<EOM
+
+Checking to see if you have nl_langinfo_l() and that it is thread-safe
+EOM
+?X: Despite claiming that nl_langinfo_l() is thread-safe, the POSIX 2008
+?X: standard allows for a non-safe implementation:
+?X:
+?X:    "nl_langinfo_l() uses an internal per-thread buffer, and nl_langinfo()
+?X:    uses (in all threads) the same buffer that nl_langinfo_l() uses in the
+?X:    initial thread. There can be interactions, but only when
+?X:    nl_langinfo_l() is called in the initial thread"
+?X:
+?X: If nl_langinfo_l() isn't thread safe, might as well just use plain
+?X: nl_langinfo().
+?X:
+?X: This program calls nl_langinfo_l(), then creates a thread, calling plain
+?X: nl_langinfo() from within it, then sees if the buffer in the original
+?X: thread was changed.
+$cat >try.c <<EOCP
+#$i_stdlib I_STDLIB
+#ifdef I_STDLIB
+#  include <stdlib.h>
+#endif
+#$i_string I_STRING
+#ifdef I_STRING
+#  include <string.h>
+#endif
+#$i_langinfo I_LANGINFO
+#ifdef I_LANGINFO
+#  include <langinfo.h>
+#endif
+#$i_pthread I_PTHREAD
+#ifdef I_PTHREAD
+#  include <pthread.h>
+#endif
+#$i_locale I_LOCALE
+#ifdef I_LOCALE
+#  include <locale.h>
+#endif
+
+void *
+thread_start(void * arg)
+{
+    nl_langinfo(RADIXCHAR);
+}
+    
+int main() {
+       char * main_buffer;
+       char save_main_buffer[1000];
+        pthread_t subthread;
+        pthread_attr_t attr;
+       
+       main_buffer = nl_langinfo_l(CODESET, newlocale(LC_ALL_MASK, "C", 0));
+
+       /* If too large for our generous allowance, just assume we don't have
+        * it. */
+       if (strlen(main_buffer) >= sizeof(save_main_buffer)) {
+           exit(1);
+       }
+
+       strcpy(save_main_buffer, main_buffer);
+
+       if (pthread_attr_init(&attr) != 0) {
+           exit(1);
+       }
+
+       if (pthread_create(&subthread, &attr, thread_start, NULL) != 0) {
+           exit(1);
+       }
+
+       if (pthread_join(subthread, NULL) != 0) {
+           exit(1);
+       }
+
+        exit(! (strcmp(main_buffer, save_main_buffer) == 0));
+}
+EOCP
+case "$usethreads" in
+    define)
+       set try
+       if eval $compile; then
+               echo "Your system has nl_langinfo_l()..." >&4
+               if $run ./try; then
+                   echo "and it is thread-safe (just as I'd hoped)." >&4
+                   d_thread_safe_nl_langinfo_l="$define"
+                   echo "$d_thread_safe_nl_langinfo_l" >&4
+               else 
+                   echo "but it isn't thread-safe, so we won't use it." >&4
+               fi
+       else
+               echo "your system does not have nl_langinfo_l()" >&4
+       fi
+       ;;
+    *) echo "Since threads aren't selected, we won't bother looking for nl_langinfo_l()" >&4
+    esac
+$rm_try
+