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)
[metaconfig.git] / U / threads / d_nl_langinfo_l.U
... / ...
CommitLineData
1?RCS: $Id$
2?RCS:
3?RCS: Copyright (c) 2017 Karl Williamson
4?RCS:
5?RCS: You may distribute under the terms of either the GNU General Public
6?RCS: License or the Artistic License, as specified in the README file.
7?RCS:
8?MAKE:d_thread_safe_nl_langinfo_l: Compile cat rm_try Oldconfig \
9 i_pthread i_stdlib i_string i_langinfo i_locale \
10 usethreads run
11?MAKE: -pick add $@ %<
12?S:d_thread_safe_nl_langinfo_l:
13?S: This variable contains the eventual value of the
14?S: HAS_THREAD_SAFE_NL_LANGINFO_L symbol, which indicates if the
15?S: nl_langinfo_l() function exists and is thread-safe.
16?S:.
17?C:HAS_THREAD_SAFE_NL_LANGINFO_L:
18?C: This symbol, when defined, indicates presence of the nl_langinfo_l()
19?C: function, and that it is thread-safe.
20?C:.
21?H:#$d_thread_safe_nl_langinfo_l HAS_THREAD_SAFE_NL_LANGINFO_L /**/
22?H:.
23?F:!try
24: check for thread_safe_nl_langinfo_l item
25$cat <<EOM
26
27Checking to see if you have nl_langinfo_l() and that it is thread-safe
28EOM
29?X: Despite claiming that nl_langinfo_l() is thread-safe, the POSIX 2008
30?X: standard allows for a non-safe implementation:
31?X:
32?X: "nl_langinfo_l() uses an internal per-thread buffer, and nl_langinfo()
33?X: uses (in all threads) the same buffer that nl_langinfo_l() uses in the
34?X: initial thread. There can be interactions, but only when
35?X: nl_langinfo_l() is called in the initial thread"
36?X:
37?X: If nl_langinfo_l() isn't thread safe, might as well just use plain
38?X: nl_langinfo().
39?X:
40?X: This program calls nl_langinfo_l(), then creates a thread, calling plain
41?X: nl_langinfo() from within it, then sees if the buffer in the original
42?X: thread was changed.
43$cat >try.c <<EOCP
44#$i_stdlib I_STDLIB
45#ifdef I_STDLIB
46# include <stdlib.h>
47#endif
48#$i_string I_STRING
49#ifdef I_STRING
50# include <string.h>
51#endif
52#$i_langinfo I_LANGINFO
53#ifdef I_LANGINFO
54# include <langinfo.h>
55#endif
56#$i_pthread I_PTHREAD
57#ifdef I_PTHREAD
58# include <pthread.h>
59#endif
60#$i_locale I_LOCALE
61#ifdef I_LOCALE
62# include <locale.h>
63#endif
64
65void *
66thread_start(void * arg)
67{
68 nl_langinfo(RADIXCHAR);
69}
70
71int main() {
72 char * main_buffer;
73 char save_main_buffer[1000];
74 pthread_t subthread;
75 pthread_attr_t attr;
76
77 main_buffer = nl_langinfo_l(CODESET, newlocale(LC_ALL_MASK, "C", 0));
78
79 /* If too large for our generous allowance, just assume we don't have
80 * it. */
81 if (strlen(main_buffer) >= sizeof(save_main_buffer)) {
82 exit(1);
83 }
84
85 strcpy(save_main_buffer, main_buffer);
86
87 if (pthread_attr_init(&attr) != 0) {
88 exit(1);
89 }
90
91 if (pthread_create(&subthread, &attr, thread_start, NULL) != 0) {
92 exit(1);
93 }
94
95 if (pthread_join(subthread, NULL) != 0) {
96 exit(1);
97 }
98
99 exit(! (strcmp(main_buffer, save_main_buffer) == 0));
100}
101EOCP
102case "$usethreads" in
103 define)
104 set try
105 if eval $compile; then
106 echo "Your system has nl_langinfo_l()..." >&4
107 if $run ./try; then
108 echo "and it is thread-safe (just as I'd hoped)." >&4
109 d_thread_safe_nl_langinfo_l="$define"
110 echo "$d_thread_safe_nl_langinfo_l" >&4
111 else
112 echo "but it isn't thread-safe, so we won't use it." >&4
113 fi
114 else
115 echo "your system does not have nl_langinfo_l()" >&4
116 fi
117 ;;
118 *) echo "Since threads aren't selected, we won't bother looking for nl_langinfo_l()" >&4
119 esac
120$rm_try
121