If mutex::try_lock() is called in a thread that already owns the mutex, the behavior is undefined. The patch fixes the issue by creating another thread, where the call is allowed.
Details
- Reviewers
ldionne davezarzycki - Group Reviewers
Restricted Project - Commits
- rG78036360573c: [libcxx testing] Fix UB in tests for std::lock_guard
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I appreciate that you're trying to make this be defined behavior, but I honestly don't know why this is UB. I can't think of or find a platform where the underlying OS "trylock" routine would have UB when called on the same thread that owns the lock already. Can somebody with access to the C++ standard provide any hint to why the standard wants this to be UB?
The current code violates the C++ standard, which says (in different sections, depending on the version):
The expression m.try_lock() shall be well-formed and have the following semantics:
Requires: If m is of type mutex, timed_mutex, shared_mutex, or shared_timed_mutex, the calling thread does not own the mutex.
The particular UB depends on the implementation and is clearly triggered on our private platform, which is why we have noticed it.
That seems correct to me: http://eel.is/c++draft/thread.mutex#requirements.mutex.general-14
Please fix the tests in C++03 mode as suggested, though.
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp | ||
---|---|---|
34–36 | With do_try_lock defined after the global mutex: void do_try_lock() { assert(m.try_lock() == false); } This is annoying, but those tests need to run in C++03 mode. |
LGTM if CI passes. I think you need to re-upload the diff for it to trigger, since the LLVM Monorepo tag was somehow removed.
With do_try_lock defined after the global mutex:
This is annoying, but those tests need to run in C++03 mode.