diff --git a/dist/ExtUtils-ParseXS/lib/perlxs.pod b/dist/ExtUtils-ParseXS/lib/perlxs.pod index aa7ccad5fe62..21f6e1c077a8 100644 --- a/dist/ExtUtils-ParseXS/lib/perlxs.pod +++ b/dist/ExtUtils-ParseXS/lib/perlxs.pod @@ -1,3 +1,5 @@ +=encoding utf8 + =head1 NAME perlxs - XS language reference manual @@ -2112,27 +2114,488 @@ than a dMY_CTX in another source file. =head2 Thread-aware system interfaces -Starting from Perl 5.8, in C/C++ level Perl knows how to wrap -system/library interfaces that have thread-aware versions -(e.g. getpwent_r()) into frontend macros (e.g. getpwent()) that -correctly handle the multithreaded interaction with the Perl -interpreter. This will happen transparently, the only thing -you need to do is to instantiate a Perl interpreter. +When you are writing code that can be used in multithreaded +applications, there are certain library calls that are unsafe to use. +For platforms that follow the POSIX standard, ALL calls EXCEPT those +listed below are B to be multi-thread-safe. The entries in the +list are flagged as follows: + +=over + +=item C

+ +Perl furnishes a thread-safe version in the POSIX module that you should +use instead, using the methods given in L. + +=item C + +Perl furnishes locking/unlocking macros specifically for this function +for you to call before invoking it, and after you've used or saved all +the necessary returns from it. For example, for C, there are +the C and C macros. + +No macro will be furnished, unless when properly invoked, using the +macro makes things completely safe. -This wrapping happens always when compiling Perl core source -(PERL_CORE is defined) or the Perl core extensions (PERL_EXT is -defined). When compiling XS code outside of the Perl core, the wrapping -does not take place before Perl 5.28. Starting in that release you can +=item C<_r> and C<_R> + +Function I has an equivalent named I>, available on some +platforms, whose result is returned in a caller-supplied space, and +which is I thread-safe, but not necessarily +completely so. You will need to refer to documentation to be sure. +C<_R> means the function is specified in the Posix standard, so it +should be available on most platforms. Lowercase C<_r> indicates that +it is an extension beyond Posix, and so support for it may be more +spotty. + +Note, however, that C<_r> applies to some functions which take a +parameter, which if not NULL, gets a copy of the return value, and +thus become thread_safe. And the C<_r> form differs only from the base +function in that they die if the parameter is NULL. + +=item C<å> and C<Å> + +These are like C<_r> and C<_R> respectively, except you can get Perl to +B change your calls of the base function to instead call +the thread-safe C<_r> version. The little circle above the letter +represents a halo (which in European culture represents purity) +representing that the substituted version is fully thread-safe (on most +platforms anyway). + +These symbols indicate that you can generally ignore thread safety +issues for these, as your code will work fine on platforms that have +them, and as good as can be expected on platforms that don't. (Likely +those other platforms will be minority platforms with few users, and you +can just say you don't support threaded operation on them.) + +To get this automatic substitution, add this line to your code: #define PERL_REENTRANT -in your code to enable the wrapping. It is advisable to do so if you -are using such functions, as intermixing the C<_r>-forms (as Perl compiled -for multithreaded operation will do) and the C<_r>-less forms is neither -well-defined (inconsistent results, data corruption, or even crashes -become more likely), nor is it very portable. Unfortunately, not all -systems have all the C<_r> forms, but using this C<#define> gives you -whatever protection that Perl is aware is available on each system. +This must follow your + + #include + +line. If you don't include F, you must instead place this line + + #include + +before your C definition. + +(This facility is available outside the perl core and its extensions +starting in Perl 5.28.) + +In some of these, the base function is thread-safe if called with a +non-NULL parameter, and the only purpose of the C<_r> version is to +fail if the call fails to use a safe form. + +=item C and C + +These are like C<å> and C<Å> respectively, except the lack of a halo +indicates that the substitued version isn't fully thread-safe. If an +C> flag also appears, wrap your calls to this function with the +Perl-furnished locking macros to get full thread-safety. Otherwise, +you'll have to examine the man pages. + +=item C + +This function returns data in a static buffer which may be destroyed by +the next call in the same thread, or on some platforms, it may be +destroyed at any time by another thread executing this function or a +related one. + +Some platforms may allocate the buffer per-thread, so it is thread-safe, +but you have to use the value (or copy it) before the next call. + +There may be a re-entrant function available in which the caller +furnishes the buffer, and which is thread-safe. Other flags on the +entry should indicate this. + +=item E + +This function accesses the program's environment. + +Writing to the environment can create a race with other threads either +reading or writing the environment at the same time. If all writers (as +the core does) protect their accesses by surrounding them with + + ENV_LOCK + ... + ENV_UNLOCK + +then the program is safe with regards to these. If this is done, then +read-only accesses can be protected by instead using + + ENV_READ_LOCK + ... + ENV_READ_UNLOCK + +calls surrounding them, which allow for any number of readers at the +same time. (A few platforms aren't safe to have multiple concurrent +readers; for these Perl automatically substitutes an exclusive lock when +you specify C, so you don't have to worry about it.) + +=item C + +This function may read the program's locale. It should be locale +thread-safe on systems with thread-safe locales. +You can wrap it within calls to + + LOCALE_READ_LOCK + ... + LOCALE_READ_UNLOCK + +to make it thread-safe with respect to locale changes by the core in all +platforms. + +If the C flag is also present, you can use + + ENVr_LOCALEr_LOCK + ... + ENVr_LOCALEr_UNLOCK + +or C ... C if the environment +needs to be locked for exclusive access. + +The functions related to formatting likely will not access the locale +unless there is a C<%> format that is locale-dependent, such as the +decimal point in floating point conversions, or thousands separators in +most numeric ones. + +=item C + +This function accesses global variables, which may be per-thread on +the platform, but are more likely process-wide. That means that another +thread may overwrite those variables before you get a chance to use +them. To overcome this, use an exclusive lock, unlocking only after you +copy to safety the contents of all the variables you need. + +Ideally, you would create a mutex for these, but you may be able to use +the C for this purpose, provided that using it doesn't unduly +slow down actual environment accesses. + +=item C<Ꞧ> + +This function has some sort of race. Generally this is due to acessing +some sort of global buffer or state internally + +=item C + +These variables must not be accessed and functions not called when +another thread is calling C. Therefore wrap them using +C. + +=item C + +These time-related functions may do writes; perhaps through an indirect +call to C, which writes to time-related global variables. +Therefore they require an exclusive lock. See C>. + +=item C<×> + +These functions should not be generally be used in a multi-thread +environment, unless only a single thread is calling them, or there is a +thread-safe reentrant version available on the platforms your code will +be run on. There may be available reentrant versions that are still not +thread-safe. You will need to scrutinize the man pages for any gotchas. + +Some of these iterate over a data structure on a per-process basis, NOT +a per-thread basis. If the perl core uses these functions, it does not +protect them, so any locking you might do around the whole iteration +process will be futile. + +Some iterate over a global data structure, and are subject to other +threads' manipulation of it. + +=back + + asctime() A L M O Ꞧ; Instead use strftime() + basename() B + catgets() B + crypt() å B + ctermid() å B unless passed a non-NULL argument + ctime() A B E L O M Ꞧ T; Instead use strftime() + daylight E L t + dbm_clearerr() + dbm_close() + dbm_delete() + dbm_error() + dbm_fetch() + dbm_firstkey() + dbm_nextkey() + dbm_open() + dbm_store() + dirname() B + dlerror() B + drand48() Ꞧ + ecvt() B O _r; Instead use my_snprintf or sv_vcatpvf + encrypt() _r + endgrent() × a G L Ꞧ + endhostent() × a E L Ꞧ + endnetent() × E L Ꞧ + endpwent() × a G L Ꞧ + endutent() Ꞧ + erand48() Ꞧ + fcvt() B O _r; Instead use my_snprintf or sv_vcatpvf + fprintf() L; Instead use XXX + ftw() + gcvt() _r O; Instead use my_snprintf or sv_vcatpvf + getchar_unlocked() unless locked by flockfile() or ftrylockfile() + getc_unlocked() unless locked by flockfile() or ftrylockfile() + getdate() E L _r + getenv() E; Instead use PerlEnv_getenv() + getgrent() × a G L Ꞧ + getgrgid() Å L + getgrnam() Å L + gethostbyaddr() å E L M O + gethostbyname() å E L M O + gethostent() × a E L Ꞧ + getlogin() × Å B L + getnetbyaddr() å L M + getnetbyname() å L M + getnetent() a E L Ꞧ + getopt() B E + getprotobyname() å B L M + getprotobynumber() å B L M + getprotoent() å B L M + getpwent() × a B L Ꞧ + getpwnam() Å L M + getpwuid() Å B L M + getservbyname() å L M + getservbyport() å L M + getservent() å L M + getspnam() å L M + getutxent() _r Ꞧ + getutxid() _r Ꞧ + getutxline() _r Ꞧ + gmtime() A E L M Ꞧ + hcreate() _r Ꞧ + hdestroy() _r Ꞧ + hsearch() _r Ꞧ + inet_ntoa() L + jrand48() Ꞧ + l64a() B + lcong48() Ꞧ + lgamma() _r G + lgammaf() _r G + lgammal() _r G + localeconv() P; for the most common uses, instead use + Perl_langinfo() for thread-safety starting with + Perl 5.28, or call POSIX::localeconv() + localtime() A E L M T + lrand48() Ꞧ + mblen() P or use mbrlen() + mbrlen() thread-safe if its 'ps' argument is non-NULL + mbrtowc() thread-safe if its 'ps' argument is non-NULL + mbsnrtowcs() thread-safe if its 'ps' argument is non-NULL + mbsrtowcs() thread-safe if its 'ps' argument is non-NULL + mbtowc() P or use mbrtowc() + mktime() E L M T + mrand48() Ꞧ + nftw() may change current working dir for every thread + nl_langinfo() (instead use Perl_langinfo() for thread-safety + starting with Perl 5.28) + nrand48() Ꞧ + printf() L; Instead use PerlIO_stdoutf + ptsname() G _r + putchar_unlocked() Ꞧ; Instead use putchar + putc_unlocked() Ꞧ; Instead use putc + putenv() E: Instead use PerlEnv_putenv + pututxline() Ꞧ + rand() _R + readdir() Å + readdir64() å + seed48() Ꞧ + setenv() E; Instead use my_setenv + setgrent() × a G L Ꞧ + sethostent() × a E L Ꞧ + setkey() _r Ꞧ + setlocale() L (instead use Perl_setlocale() for thread-safety + starting with Perl 5.28) + setnetent() × E L Ꞧ + setpwent() × a B L Ꞧ + setutxent() Ꞧ + sleep() S XXX + snprintf() L; Instead use my_snprintf() + sprintf() L; Instead use my_snprintf() + srand48() Ꞧ + strerror() B Å + strftime() E L M + strsignal() B L + strtok() B _R + system() + tmpnam() å; thread-safe if its argument is non-non-NULL; + considered obsolete; + ttyname() B Å + tzset() _r E G L M T + tzname E L t + timezone E L t + unsetenv() E + usleep() O; Instead use nanosleep + vfprintf() L; Instead use PerlIO_vprintf + vprintf() L; Instead use PerlIO_vprintf + vsnprintf() L; Instead use my_vsnprintf() + vsprintf() L; Instead use my_vsnprintf() + wcrtomb() L; thread-safe if its 'ps' argument is non-NULL + wcsnrtombs() L; thread-safe if its 'ps' argument is non-NULL + wcsrtombs() L; thread-safe if its 'ps' argument is non-NULL + wcstombs() L; use wcsrtombs() instead + wctomb() L P or use wcrtomb() + + rpmatch:LC_ALL + strcoll:LC_COLLATE + strverscmp:LC_COLLATE + strxfrm:LC_COLLATE + sysconf:LC_COLLATE + btowc:LC_CTYPE + fgetwc:LC_CTYPE + fgetws:LC_CTYPE + fputwc:LC_CTYPE + fputws:LC_CTYPE + getwchar:LC_CTYPE + iswalnum:LC_CTYPE + iswalpha:LC_CTYPE + iswblank:LC_CTYPE + iswcntrl:LC_CTYPE + iswctype:LC_CTYPE + iswdigit:LC_CTYPE + iswgraph:LC_CTYPE + iswlower:LC_CTYPE + iswprint:LC_CTYPE + iswpunct:LC_CTYPE + iswspace:LC_CTYPE + iswupper:LC_CTYPE + iswxdigit:LC_CTYPE + mblen:LC_CTYPE + mbrlen:LC_CTYPE + mbrtowc:LC_CTYPE + mbsinit:LC_CTYPE + mbsnrtowcs:LC_CTYPE + mbsrtowcs:LC_CTYPE + mbstowcs:LC_CTYPE + mbtowc:LC_CTYPE + putwchar:LC_CTYPE + strcasecmp:LC_CTYPE + towctrans:LC_CTYPE + towlower:LC_CTYPE + towupper:LC_CTYPE + ungetwc:LC_CTYPE + wcrtomb:LC_CTYPE + wcscasecmp:LC_CTYPE + wcsncasecmp:LC_CTYPE + wcsnrtombs:LC_CTYPE + wcsrtombs:LC_CTYPE + wcstombs:LC_CTYPE + wcswidth:LC_CTYPE + wctob:LC_CTYPE + wctomb:LC_CTYPE + wctrans:LC_CTYPE + wctype:LC_CTYPE + wcwidth:LC_CTYPE + wprintf:LC_CTYPE + nl_langinfo:LC_CTYPE CODESET + catopen:LC_MESSAGES + rpmatch:LC_MESSAGES + strerror:LC_MESSAGES + nl_langinfo:LC_MESSAGES NOEXPR + nl_langinfo:LC_MESSAGES YESEXPR + localeconv:LC_MONETARY LC_NUMERIC + strfmon:LC_MONETARY LC_NUMERIC + nl_langinfo:LC_MONETARY CRNCYSTR + localeconv:LC_MONETARY LC_NUMERIC + printf:LC_NUMERIC + scanf:LC_NUMERIC + strfmon:LC_MONETARY LC_NUMERIC + strfromd:LC_NUMERIC + nl_langinfo:LC_NUMERIC RADIXCHAR + nl_langinfo:LC_NUMERIC THOUSEP + getdate:LC_TIME + strftime:LC_TIME + strptime:LC_TIME + nl_langinfo:LC_TIME ABDAY_ + nl_langinfo:LC_TIME ABMON_ + nl_langinfo:LC_TIME DAY_ + nl_langinfo:LC_TIME D_FMT + nl_langinfo:LC_TIME D_T_FMT + nl_langinfo:LC_TIME MON_ + nl_langinfo:LC_TIME T_FMT + +(The list is taken from the POSIX 2001 and 2008 +(L) +standards, supplemented by the Linux man pages project 4.09 +L and others.) + +The above list should unfortunately be taken as just a starting point, +as it is not entirely correct, for several reasons. + +=over + +=item * + +The documentation is incomplete and not entirely consistent. In +researching this document, omissions were discovered in the source +documentation, and added to the above list. For example, C is +supposed to be thread-safe in the POSIX standard, but elsewhere in the +same document, under C, it says that C effectively +calls C which does writes to globals, and hence isn't thread +safe. + +=item * + +Some systems will have additional functions, not defined by Posix, and +which aren't thread-safe. For example, any function that gets the value +of any environment variable will almost certainly be thread-unsafe in +the presence of another thread changing the environment at the same +time. + +=item * + +Some systems have deviated from Posix and have thread-unsafe functions +that the Standard mandates should be safe. A big example of this is +Linux in which many functions, such as any of the C variants +are not safe if the process's global locale is changed by another thread +in the middle of their execution. (This is no longer a problem starting +in Perl 5.28 on systems that have per-thread locales.) + +Another example is C, which again uses the locale, but also +may call C which accesses the environment. + +=item * + +Any function that returns its result in an internal static area common +to more than one thread is actually unsafe, whether or not it is on the +list. This is because another thread can take control at just the wrong +moment and change that area before the result can be saved or acted +upon. These CANNOT be made thread-safe without cooperation by ALL +code that could access the static area at the same time in other +threads. You might have trouble convincing the maintainers of such code +to fix it. At the least, the C definition given above +should be done. + +And, unfortunately this isn't the whole story. Some such reentrant +functions still aren't fully thread-safe. For example, +C is supposed to be thread-safe, and that is true if +plain C is never called, but the POSIX standard allows an +implementation to have plain C overwrite the +C buffer under some circumstances, and vice versa. + +=item * + +Unfortunately, there are systems that deviate from the POSIX standard +and implement some unlisted functions unsafely. The system's +documentation should specify this, but there are sometimes errors in the +documentation. + +=item * + +Some systems may have chosen to implement some of the listed functions +in a thread-safe manner. This means that code you have written to work +around the issue for other systems will be wasted on ones where the +function is thread-safe. There are some macros XXX defined to help you +in this regard. An example is that some versions of Linux claim to +implement C safely + +=back =head1 EXAMPLES @@ -2393,9 +2856,11 @@ thread using an alien library without a problem; but no more than a single thread can be so-occupied. Bad results likely will happen. In perls without multi-thread locale support, some alien libraries, -such as C change locales. This can cause problems for the Perl -core and other modules. For these, before control is returned to -perl, starting in v5.20.1, calling the function +such as C (including C) change locales. This can cause problems +for the Perl core and other modules. Unless C +has been called as described above, these libraries won't know what the +current locale Perl has set actually is. But also, before control is +returned to perl, starting in v5.20.1, calling the function L from XS should be sufficient to avoid most of these problems. Prior to this, you need a pure Perl statement that does this: @@ -2427,3 +2892,5 @@ details so they are only useful to the maintainer of the XS code itself. Originally written by Dean Roehrich >. Maintained since 1996 by The Perl Porters >. +=item C<×> + getlogin() × å diff --git a/t/porting/known_pod_issues.dat b/t/porting/known_pod_issues.dat index b76304165227..c7fb539737ce 100644 --- a/t/porting/known_pod_issues.dat +++ b/t/porting/known_pod_issues.dat @@ -282,6 +282,7 @@ printf(3) provide ptar(1) ptargrep(1) +pthreads(7) pwd_mkdb(8) querylocale(3) RDF::Trine