Title
Specify when once_flag becomes invalid
Status
c++14
Section
[thread.once]
Submitter
Nicolai Josuttis

Created on 2011-08-30.00:00:00 last changed 131 months ago

Messages

Date: 2013-04-19.22:36:19

Proposed resolution:

This wording is relative to N3337.

  1. Change [thread.once.callonce] as indicated:

    template<class Callable, class ...Args>
    void call_once(once_flag& flag, Callable&& func, Args&&... args);
    

    […]

    -4- Throws: system_error when an exception is required (30.2.2), or any exception thrown by func.

    -5- Error conditions:

    • invalid_argument — if the once_flag object is no longer valid.
Date: 2013-04-20.00:00:00

[ 2013-04-20 Bristol ]

Date: 2012-11-02.22:48:46

[ 2012, Portland: move to Tentatively Ready ]

Concurrency move to Ready, pending LWG review.

LWG did not have time to perform the final review in Portland, so moving to tentatively ready to reflect the Concurrency belief that the issue is ready, but could use a final inspection from library wordsmiths.

Date: 2012-02-13.21:55:45

[ 2012, Kona ]

Remove error conditions, move to Review.

Date: 2011-08-30.00:00:00

In function call_once [thread.once.callonce] paragraph 4 and 5 specify for call_once():

Throws: system_error when an exception is required ([thread.req.exception]), or any exception thrown by func.

Error conditions:

  • invalid_argument — if the once_flag object is no longer valid.

However, nowhere in [thread.once] is specified, when a once-flag becomes invalid.

As far as I know this happens if the flag is used for different functions. So we either have to have to insert a sentence/paragraph in

30.4.4.2 Function call_once [thread.once.callonce]

or

30.4.4 Call once [thread.once]

explaining when a once_flag becomes invalidated or we should state as error condition something like:

  • invalid_argument — if the func used in combination with the once_flag is different from a previously passed func for the same once_flag

Anthony Williams:

A once_flag is invalidated if you destroy it (e.g. it is an automatic object, or heap allocated and deleted, etc.)

If the library can detect that this is the case then it will throw this exception. If it cannot detect such a case then it will never be thrown.

Jonathan Wakely:

I have also wondered how that error can happen in C++, where the type system will reject a non-callable type being passed to call_once() and should prevent a once_flag being used after its destructor runs.

If a once_flag is used after its destructor runs then it is indeed undefined behaviour, so implementations are already free to throw any exception (or set fire to a printer) without the standard saying so.

My assumption was that it's an artefact of basing the API on pthreads, which says:

The pthread_once() function may fail if:

[EINVAL] If either once_control or init_routine is invalid.

Pete Becker:

Yes, probably. We had to clean up several UNIXisms that were in the original design.

History
Date User Action Args
2014-02-20 13:20:35adminsetstatus: wp -> c++14
2013-04-25 19:07:07adminsetstatus: voting -> wp
2013-04-19 22:36:19adminsetmessages: + msg6478
2013-04-19 22:36:19adminsetstatus: ready -> voting
2012-10-19 07:50:57adminsetmessages: + msg6180
2012-10-19 07:50:57adminsetstatus: review -> ready
2012-02-13 21:55:45adminsetmessages: + msg6011
2012-02-13 21:55:45adminsetmessages: + msg6010
2012-02-13 21:55:45adminsetstatus: new -> review
2011-08-30 00:00:00admincreate