Skip to content

<mutex>: Is _Mutex_base::try_lock actually noexcept? #3324

@CaseyCarter

Description

@CaseyCarter

@strega-nil-ms observed in https://github.com/microsoft/STL/pull/3321/files#r1060904759 that _Mutex_base::try_lock (which implements try_lock for all of the standard mutex types) is not marked noexcept despite that the Standard says it "Throws: Nothing". In fact, the function calls _Throw_C_error:

STL/stl/inc/mutex

Lines 51 to 61 in 8ddf4da

_NODISCARD_TRY_CHANGE_STATE bool try_lock() {
const auto _Res = _Mtx_trylock(_Mymtx());
switch (_Res) {
case _Thrd_success:
return true;
case _Thrd_busy:
return false;
default:
_Throw_C_error(_Res);
}
}

which throws system_error:

STL/stl/src/thread0.cpp

Lines 34 to 53 in 8ddf4da

[[noreturn]] _CRTIMP2_PURE void __cdecl _Throw_Cpp_error(int code) { // throw error object
_THROW(system_error(static_cast<int>(codes[code]), _STD generic_category(), msgs[code]));
}
[[noreturn]] _CRTIMP2_PURE void __cdecl _Throw_C_error(int code) { // throw error object for C error
switch (code) { // select the exception
case _Thrd_nomem:
case _Thrd_timedout:
_Throw_Cpp_error(_RESOURCE_UNAVAILABLE_TRY_AGAIN);
case _Thrd_busy:
_Throw_Cpp_error(_DEVICE_OR_RESOURCE_BUSY);
case _Thrd_error:
_Throw_Cpp_error(_INVALID_ARGUMENT);
default:
_CSTD abort();
}
}

Either (1) we're not conforming, or (2) _Mutex_base::try_lock only throws on violation of the precondition in [thread.mutex.requirements.mutex.general]/14: "If m is of type mutex, timed_mutex, shared_mutex, or shared_timed_mutex, the calling thread does not own the mutex". If (2) is the case, we should convert the throw into an assertion failure. If (1), we should fix it. In either case, it would be nice to strengthen noexcept for _Mutex_base::try_lock.

(I'll tag this as a bug until we investigate. (1) is certainly a bug, but (2) an enhancement.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions