<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<title>Thread Unsafe Standard Functions</title>
</head>
<body>
<h1>Thread Unsafe Standard Functions</h1>

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

<p>
Lawrence Crowl, crowl@google.com, Lawrence@Crowl.org<br>
P.J. Plauger, pjp@dinkumware.com<br>
Nick Stoughton, USENIX, nick@usenix.org
</p>

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

<p>
Revisions consist of:
</p>
<ul>
<li>
A joint paper with ISO WG14 C as liason information.
</li>
<li>
A clarification that it is function calls that may race, not functions.
</li>
<li>
A clarification that groups of function may race with each other.
</li>
<li>
Removal of some listed functions that are not part of the C or C++ standards.
</li>
<li>
Addition of the requirements on floating-point environment.
</li>
</ul>


<h2>Introduction</h2>

<p>
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].
</p>


<h3>Already Exempted</h3>

<p>
The following functions
are already exempted in 20.9 [date.time].
</p>
<blockquote>
<p>
<code>
asctime
ctime
gmtime
localtime
</code>
</p>
</blockquote>

<p>
The following functions
are already exempted in 21.5 [c.strings].
</p>
<blockquote>
<p>
<code>
strerror
strtok
</code>
</p>
</blockquote>


<p>
The following functions
are already exempted in 26.7 [c.math].
</p>
<blockquote>
<p>
<code>
rand
</code>
</p>
</blockquote>


<h3>Exemption Revoked</h3>

<p>
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.
</p>
<blockquote>
<p>
<code>
atexit
at_quick_exit
exit
fclose
free
quick_exit
malloc
signal
</code>
</p>
</blockquote>

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


<h3>Locales</h3>

<p>
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;
<code>setlocale()</code> is thread-unsafe. 
</p>


<h2>Wording</h2>

<p>
The wording changes are relative to N2800.
</p>


<h3>18.4 Start and termination [support.start.term]</h3>

<p>
Edit paragraph 4 as follows.
</p>
<blockquote>
<p>
<i>Effects:</i>
The <code>atexit()</code> functions
register the function pointed to by <code>f</code>
to be called without arguments at normal program termination.
<ins>It is unspecified whether a call to <code>atexit()</code>
that does not happen-before (1.10) a call to <code>exit()</code>
will succeed.</ins>
<ins>[<i>Note:</i>
The <code>atexit()</code> functions
shall not introduce a data race (17.6.5.7).
&mdash;<i>end note</i>]</ins>
</p>
</blockquote>

<p>
Edit paragraph 9 as follows.
</p>
<blockquote>
<p>
<i>Effects:</i>
The <code>at_quick_exit()</code> functions
register the function pointed to by <code>f</code>
to be called without arguments
when <code>quick_exit</code> is called.
<ins>It is unspecified whether a call to <code>at_quick_exit()</code>
that does not happen-before (1.10) a call to <code>quick_exit()</code>
will succeed.</ins>
<ins>[<i>Note:</i></ins>
The <code>at_quick_exit()</code> functions
shall <del>be thread safe.</del>
<ins>not introduce a data race (17.6.5.7).
&mdash;<i>end note</i>]</ins>
[<i>Note:</i>
The <code>at_quick_exit</code> registrations
are distinct from the <code>atexit</code> registrations,
and applications may need to call both registration functions
with the same argument.
&mdash;<i>end note</i>]
</p>
</blockquote>


<h3>18.9 Other runtime support [support.runtime]</h3>

<p>
After paragraph 4, add a new paragraph.
</p>
<blockquote>
<p>
<ins>
Calls to the function <code>getenv</code>
shall not introduce a data race (17.6.5.7)
provided that nothing modifies the environment.
[<i>Note:</i>
Calls to the POSIX functions <code>setenv</code> and <code>putenv</code>
modify the environment.
&mdash;<i>end note</i>]
</ins>
</p>
</blockquote>


<h3>21.5 Null-terminated sequence utilities [c.strings]</h3>

<p>
After paragraph 14, add a new paragraph.
</p>
<blockquote>
<p>
<ins>
Calling the following functions
with a <code>mbstate_t*</code> argument of <code>NULL</code>
may introduce a
data race (17.6.5.7)
with other calls to these functions
with a <code>mbstate_t*</code> argument of <code>NULL</code>.
</ins>
</p>
<blockquote>
<p>
<ins>
<code>
mbrlen
mbrtowc
mbsrtowc
mbtowc
wcrtomb
wcsrtomb
wctomb
</code>
</ins>
</p>
</blockquote>
</blockquote>


<h3>22.1.1.5 locale static members [locale.statics]</h3>

<p>
Edit paragraph 2 as follows.
</p>
<blockquote>
<p>
<i>Effects:</i>
Causes future calls to the constructor <code>locale()</code>
to return a copy of the argument.
If the argument has a name,
does
</p>
<blockquote>
<p>
<code>
std::setlocale(LC_ALL, loc.name().c_str());
</code>
</p>
</blockquote>
<p>
otherwise, the effect on the C locale, if any, is implementation-defined.
No library function other than <code>locale::global()</code>
shall affect the value returned by <code>locale()</code>.
<ins>
[<i>Note:</i>
See (22.4 [c.locales]) for data race considerations
when <code>setlocale</code> is invoked.
&mdash;<i>end note</i>]
</ins>
</p>
</blockquote>


<h3>22.4 C Library Locales [c.locales]</h3>

<p>
After paragraph 2, add new paragraph.
</p>
<blockquote>
<p>
<ins>
Calls to the function <code>setlocale</code>
may introduce a data race (17.6.5.7)
with other calls to <code>setlocale</code>
or with calls to the following functions.
</ins>
</p>
<blockquote>
<p>
<ins>
<code>
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
</code>
</ins>
</p>
</blockquote>
</blockquote>


<h3>26.2.1 Header <code>&lt;cfenv&gt;</code> synopsis [cfenv.syn]</h3>

<p>
After paragraph 2, add a new paragraph.
</p>
<blockquote>
<p>
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 <code>std::thread</code> object
(30.2.1 [thread.thread.class])
at the time it constructed the object.
[<i>Note:</i>
That is, the child thread gets the floating-point state
of the parent thread at the time of the child's creation.
&mdash;<i>end note</i>]
</ins>
</p>
</blockquote>


<h3>27.8.2 C Library files [c.files]</h3>

<p>
Before "See also", add a new paragraph.
</p>
<blockquote>
<p>
<ins>
Calls to the function <code>tmpnam</code>
with an argument of <code>NULL</code>
may introduce a data race (17.6.5.7)
with other calls to <code>tmpnam</code>
with an argument of <code>NULL</code>.
</ins>
</p>
</blockquote>
</body>
</html>
