Thread Unsafe Standard Functions

ISO/IEC JTC1 SC22 WG21 N2864 = 09-0054 - 2009-03-21
ISO/IEC JTC 1/SC 22/WG 14 N1371 - 2009-03-21

Lawrence Crowl, crowl@google.com, Lawrence@Crowl.org
P.J. Plauger, pjp@dinkumware.com
Nick Stoughton, USENIX, nick@usenix.org

This paper is a revision of ISO/IEC JTC1 SC22 WG21 N2827 = 09-0017 - 2009-02-07.

Revisions consist of:

Introduction

With the introduction of concurrency into the C++ standard, some functions adopted from the C standard need explicit exemption from the general prohibition on data races in 17.6.5.7 [res.on.data.races].

Already Exempted

The following functions are already exempted in 20.9 [date.time].

asctime ctime gmtime localtime

The following functions are already exempted in 21.5 [c.strings].

strerror strtok

The following functions are already exempted in 26.7 [c.math].

rand

Exemption Revoked

The following functions may have previously been thread unsafe, but must be thread safe to enable effective programming. By failng to mention these functions, the standard implicitly requires them to be thread safe.

atexit at_quick_exit exit fclose free quick_exit malloc signal

The draft standard does not say what happens when a call to atexit does not happen before exit. We propose to make whether or not the function is registered unspecified. Likewise for at_quick_exit and quick_exit.

Locales

The Posix/C++ Binding group suggests that LWG issue 708 be closed as Not-A-Defect. C++ locale objects are already adequate for thread-safe locales; setlocale() is thread-unsafe.

Wording

The wording changes are relative to N2800.

18.4 Start and termination [support.start.term]

Edit paragraph 4 as follows.

Effects: The atexit() functions register the function pointed to by f to be called without arguments at normal program termination. It is unspecified whether a call to atexit() that does not happen-before (1.10) a call to exit() will succeed. [Note: The atexit() functions shall not introduce a data race (17.6.5.7). —end note]

Edit paragraph 9 as follows.

Effects: The at_quick_exit() functions register the function pointed to by f to be called without arguments when quick_exit is called. It is unspecified whether a call to at_quick_exit() that does not happen-before (1.10) a call to quick_exit() will succeed. [Note: The at_quick_exit() functions shall be thread safe. not introduce a data race (17.6.5.7). —end note] [Note: The at_quick_exit registrations are distinct from the atexit registrations, and applications may need to call both registration functions with the same argument. —end note]

18.9 Other runtime support [support.runtime]

After paragraph 4, add a new paragraph.

Calls to the function getenv shall not introduce a data race (17.6.5.7) provided that nothing modifies the environment. [Note: Calls to the POSIX functions setenv and putenv modify the environment. —end note]

21.5 Null-terminated sequence utilities [c.strings]

After paragraph 14, add a new paragraph.

Calling the following functions with a mbstate_t* argument of NULL may introduce a data race (17.6.5.7) with other calls to these functions with a mbstate_t* argument of NULL.

mbrlen mbrtowc mbsrtowc mbtowc wcrtomb wcsrtomb wctomb

22.1.1.5 locale static members [locale.statics]

Edit paragraph 2 as follows.

Effects: Causes future calls to the constructor locale() to return a copy of the argument. If the argument has a name, does

std::setlocale(LC_ALL, loc.name().c_str());

otherwise, the effect on the C locale, if any, is implementation-defined. No library function other than locale::global() shall affect the value returned by locale(). [Note: See (22.4 [c.locales]) for data race considerations when setlocale is invoked. —end note]

22.4 C Library Locales [c.locales]

After paragraph 2, add new paragraph.

Calls to the function setlocale may introduce a data race (17.6.5.7) with other calls to setlocale or with calls to the following functions.

fprintf fscanf isalnum isalpha isblank iscntrl isdigit isgraph islower isprint ispunct isspace isupper iswalnum iswalpha iswblank iswcntrl iswctype iswdigit iswgraph iswlower iswprint iswpunct iswspace iswupper iswxdigit isxdigit localeconv mblen mbstowcs mbtowc setlocale strcoll strerror strtod strxfrm tolower toupper towlower towupper wcscoll wcstod wcstombs wcsxfrm wctomb

26.2.1 Header <cfenv> synopsis [cfenv.syn]

After paragraph 2, add a new paragraph.

The floating-point environment has thread storage duration (3.7.2 [basic.stc.thread]). The initial state for a thread's floating-point environment is the state of the floating-point environment of the thread that constructs the corresponding std::thread object (30.2.1 [thread.thread.class]) at the time it constructed the object. [Note: That is, the child thread gets the floating-point state of the parent thread at the time of the child's creation. —end note]

27.8.2 C Library files [c.files]

Before "See also", add a new paragraph.

Calls to the function tmpnam with an argument of NULL may introduce a data race (17.6.5.7) with other calls to tmpnam with an argument of NULL.