Section: 32.6.7.2 [thread.once.callonce] Status: C++11 Submitter: INCITS Opened: 2010-08-25 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [thread.once.callonce].
View all issues with C++11 status.
Discussion:
Addresses US-190
The term "are serialized" is never defined (32.6.7.2 [thread.once.callonce] p. 2).
[ Resolution proposed by ballot comment: ]
Remove the sentence with "are serialized" from
paragraph 2. Add "Calls to call_once
on the same
once_flag
object shall not introduce data races
(17.6.4.8)." to paragraph 3.
[ 2010-11-01 Daniel translates NB comment into wording ]
[ 2011-02-17: Hans proposes an alternative resolution ]
[ 2011-02-25: Hans, Clark, and Lawrence update the suggested wording ]
[2011-02-26 Reflector discussion]
Moved to Tentatively Ready after 5 votes.
Proposed resolution:
Change 32.6.7.2 [thread.once.callonce] p.2+3 as indicated:
template<class Callable, class ...Args> void call_once(once_flag& flag, Callable&& func, Args&&... args);[..]
2 Effects:Calls toAn execution ofcall_once
on the sameonce_flag
object are serialized. If there has been a prior effective call tocall_once
on the sameonce_flag object
, the call tocall_once
returns without invokingfunc
. If there has been no prior effective call tocall_once
on the sameonce_flag
object,INVOKE(decay_copy( std::forward<Callable>(func)), decay_copy(std::forward<Args>(args))...)
is executed. The call tocall_once
is effective if and only ifINVOKE(decay_copy( std::forward<Callable>(func)), decay_copy(std::forward<Args>(args))...)
returns without throwing an exception. If an exception is thrown it is propagated to the caller.call_once
that does not call itsfunc
is a passive execution. An execution ofcall_once
that calls itsfunc
is an active execution. An active execution shall callINVOKE(decay_copy(std::forward<Callable>(func)), decay_copy(std::forward<Args>(args))...)
. If such a call tofunc
throws an exception, the execution is exceptional, otherwise it is returning. An exceptional execution shall propagate the exception to the caller ofcall_once
. Among all executions ofcall_once
for any givenonce_flag
: at most one shall be a returning execution; if there is a returning execution, it shall be the last active execution; and there are passive executions only if there is a returning execution. [Note: Passive executions allow other threads to reliably observe the results produced by the earlier returning execution. — end note] 3 Synchronization:The completion of an effective call toFor any givencall_once
on aonce_flag
object synchronizes with (6.9.2 [intro.multithread]) all subsequent calls tocall_once
on the sameonce_flag
object.once_flag
: all active executions occur in a total order; completion of an active execution synchronizes with (6.9.2 [intro.multithread]) the start of the next one in this total order; and the returning execution synchronizes with the return from all passive executions.