Mutex, timed_mutex, and call_once are not fully standard-compliant
Closed this issue · 2 comments
nmcclatchey commented
Certain parts of the existing classes are not fully standard compliant. This comment lists them, lest we forget.
- Classes
mutex
andtimed_mutex
do not satisfy the StandardLayoutType concept. (Will be fixed by #36)- Adding the variable
mOwnerThread
violates the requirement for the inheritance tree to have only one class that defines non-static members. - Compliance is practical, but possibly undesired.
- Recursively locking a non-recursive mutex is undefined behavior.
- Compliance would either remove error-checking code or bloat the recursive mutex classes.
- Adding the variable
- Class
mutex
must have aconstexpr
constructor, but will not if bothNDEBUG
andSTDMUTEX_NO_RECURSION_CHECKS
are defined. (Will be fixed by #36)- Causes a compiler error to be thrown by
once_flag
.- If necessary,
once_flag
andcall_once
can be rewritten to use only anatomic_char
and itscompare_exchange_weak
function, rather than depending on themutex
implementation. Efficiency of this implementation could be improved in Windows 8 by using WaitOnAddress. See #36
- If necessary,
- Compliance is impractical for Windows XP and Windows Vista.
- Static initialization is not supported for CRITICAL_SECTION objects.
- Compliance is possible for Windows 7.
- Using a Slim Reader/Writer (SRW) lock, as in
shared_mutex
, would allow static initialization from a compile-time constant.
- Using a Slim Reader/Writer (SRW) lock, as in
- Causes a compiler error to be thrown by
- Function
call_once
, and thethread
constructor, do not behave as if callinginvoke
. In particular, member function pointers are not handled correctly. Member data members are less of a concern in this context, but still must be handled for standard compliance.- Compliance is possible.
- If compiling for C++17, simply use
invoke
. - If compiling for C++11, use a helper class and template specialization to define an equivalent of
invoke
early.
- If compiling for C++17, simply use
- Compliance is possible.
alxvasilev commented
According to cppreference.com, std::invoke is C++17, and std::call_once is C++11. If this is correct, the C++11 standard cannot require the implementation to use std::invoke
nmcclatchey commented
The cppreference.com site is somewhat inconsistent there. The call_once documentation indicates that invoke
ought to be used before C++17, despite invoke
being a C++17 feature. I think the intent is "call as if by invoke
", which is still not quite satisfied by the current implementation.
I will adjust the issue accordingly.