diff --git a/stl/inc/mutex b/stl/inc/mutex index 1d4faf58c4..ed72ac0834 100644 --- a/stl/inc/mutex +++ b/stl/inc/mutex @@ -93,11 +93,7 @@ public: _Mtx_unlock(_Mymtx()); } - using native_handle_type = void*; - - _NODISCARD native_handle_type native_handle() noexcept /* strengthened */ { - return _Mtx_getconcrtcs(_Mymtx()); - } + // native_handle_type and native_handle() have intentionally been removed. See GH-3820. protected: _NODISCARD_TRY_CHANGE_STATE bool _Verify_ownership_levels() noexcept { @@ -636,8 +632,6 @@ _EXPORT_STD enum class cv_status { // names for wait returns _EXPORT_STD class condition_variable { // class for waiting for conditions public: - using native_handle_type = _Cnd_t; - condition_variable() noexcept /* strengthened */ { _Cnd_init_in_situ(_Mycnd()); } @@ -725,9 +719,7 @@ public: return _Wait_until1(_Lck, _Abs_time, _Pred); } - _NODISCARD native_handle_type native_handle() noexcept /* strengthened */ { - return _Mycnd(); - } + // native_handle_type and native_handle() have intentionally been removed. See GH-3820. void _Register(unique_lock& _Lck, int* _Ready) noexcept { // register this object for release at thread exit _Cnd_register_at_thread_exit(_Mycnd(), _Lck.release()->_Mymtx(), _Ready); diff --git a/stl/src/cond.cpp b/stl/src/cond.cpp index e9eb1c642b..153b59974e 100644 --- a/stl/src/cond.cpp +++ b/stl/src/cond.cpp @@ -15,9 +15,9 @@ struct _Cnd_internal_imp_t { // condition variable implementation for ConcRT typename std::_Aligned_storage::type cv; - [[nodiscard]] Concurrency::details::stl_condition_variable_interface* _get_cv() noexcept { + [[nodiscard]] Concurrency::details::stl_condition_variable_win7* _get_cv() noexcept { // get pointer to implementation - return reinterpret_cast(&cv); + return reinterpret_cast(&cv); } }; @@ -28,9 +28,7 @@ void _Cnd_init_in_situ(const _Cnd_t cond) { // initialize condition variable in Concurrency::details::create_stl_condition_variable(cond->_get_cv()); } -void _Cnd_destroy_in_situ(const _Cnd_t cond) { // destroy condition variable in situ - cond->_get_cv()->destroy(); -} +void _Cnd_destroy_in_situ(_Cnd_t) {} // destroy condition variable in situ int _Cnd_init(_Cnd_t* const pcond) { // initialize *pcond = nullptr; @@ -53,7 +51,7 @@ void _Cnd_destroy(const _Cnd_t cond) { // clean up } int _Cnd_wait(const _Cnd_t cond, const _Mtx_t mtx) { // wait until signaled - const auto cs = static_cast(_Mtx_getconcrtcs(mtx)); + const auto cs = static_cast(_Mtx_getconcrtcs(mtx)); _Mtx_clear_owner(mtx); cond->_get_cv()->wait(cs); _Mtx_reset_owner(mtx); @@ -63,7 +61,7 @@ int _Cnd_wait(const _Cnd_t cond, const _Mtx_t mtx) { // wait until signaled // wait until signaled or timeout int _Cnd_timedwait(const _Cnd_t cond, const _Mtx_t mtx, const _timespec64* const target) { int res = _Thrd_success; - const auto cs = static_cast(_Mtx_getconcrtcs(mtx)); + const auto cs = static_cast(_Mtx_getconcrtcs(mtx)); if (target == nullptr) { // no target time specified, wait on mutex _Mtx_clear_owner(mtx); cond->_get_cv()->wait(cs); diff --git a/stl/src/mutex.cpp b/stl/src/mutex.cpp index dad5b4f765..6deb0e8ebd 100644 --- a/stl/src/mutex.cpp +++ b/stl/src/mutex.cpp @@ -43,8 +43,8 @@ struct _Mtx_internal_imp_t { // ConcRT mutex Concurrency::details::stl_critical_section_max_alignment>::type cs; long thread_id; int count; - Concurrency::details::stl_critical_section_interface* _get_cs() { // get pointer to implementation - return reinterpret_cast(&cs); + [[nodiscard]] Concurrency::details::stl_critical_section_win7* _get_cs() { // get pointer to implementation + return reinterpret_cast(&cs); } }; @@ -65,7 +65,7 @@ void _Mtx_init_in_situ(_Mtx_t mtx, int type) { // initialize mutex in situ void _Mtx_destroy_in_situ(_Mtx_t mtx) { // destroy mutex in situ _THREAD_ASSERT(mtx->count == 0, "mutex destroyed while busy"); - mtx->_get_cs()->destroy(); + (void) mtx; } int _Mtx_init(_Mtx_t* mtx, int type) { // initialize mutex @@ -126,7 +126,7 @@ static int mtx_do_lock(_Mtx_t mtx, const _timespec64* target) { // lock mutex while (now.tv_sec < target->tv_sec || now.tv_sec == target->tv_sec && now.tv_nsec < target->tv_nsec) { // time has not expired if (mtx->thread_id == static_cast(GetCurrentThreadId()) - || mtx->_get_cs()->try_lock_for(_Xtime_diff_to_millis2(target, &now))) { // stop waiting + || mtx->_get_cs()->try_lock()) { // stop waiting res = WAIT_OBJECT_0; break; } else { diff --git a/stl/src/primitives.hpp b/stl/src/primitives.hpp index a61e775547..b3d2db3236 100644 --- a/stl/src/primitives.hpp +++ b/stl/src/primitives.hpp @@ -10,25 +10,7 @@ namespace Concurrency { namespace details { - class __declspec(novtable) stl_critical_section_interface { - public: - virtual void lock() = 0; - virtual bool try_lock() = 0; - virtual bool try_lock_for(unsigned int) = 0; - virtual void unlock() = 0; - virtual void destroy() = 0; - }; - - class __declspec(novtable) stl_condition_variable_interface { - public: - virtual void wait(stl_critical_section_interface*) = 0; - virtual bool wait_for(stl_critical_section_interface*, unsigned int) = 0; - virtual void notify_one() = 0; - virtual void notify_all() = 0; - virtual void destroy() = 0; - }; - - class stl_critical_section_win7 final : public stl_critical_section_interface { + class stl_critical_section_win7 { public: stl_critical_section_win7() = default; @@ -36,22 +18,15 @@ namespace Concurrency { stl_critical_section_win7(const stl_critical_section_win7&) = delete; stl_critical_section_win7& operator=(const stl_critical_section_win7&) = delete; - void destroy() override {} - - void lock() override { + void lock() { AcquireSRWLockExclusive(&m_srw_lock); } - bool try_lock() override { + bool try_lock() { return TryAcquireSRWLockExclusive(&m_srw_lock) != 0; } - bool try_lock_for(unsigned int) override { - // STL will call try_lock_for once again if this call will not succeed - return stl_critical_section_win7::try_lock(); - } - - void unlock() override { + void unlock() { _Analysis_assume_lock_held_(m_srw_lock); ReleaseSRWLockExclusive(&m_srw_lock); } @@ -61,50 +36,46 @@ namespace Concurrency { } private: + void* unused = nullptr; // TRANSITION, ABI: was the vptr SRWLOCK m_srw_lock = SRWLOCK_INIT; }; - class stl_condition_variable_win7 final : public stl_condition_variable_interface { + class stl_condition_variable_win7 { public: - stl_condition_variable_win7() { - InitializeConditionVariable(&m_condition_variable); - } + stl_condition_variable_win7() = default; ~stl_condition_variable_win7() = delete; stl_condition_variable_win7(const stl_condition_variable_win7&) = delete; stl_condition_variable_win7& operator=(const stl_condition_variable_win7&) = delete; - void destroy() override {} - - void wait(stl_critical_section_interface* lock) override { - if (!stl_condition_variable_win7::wait_for(lock, INFINITE)) { + void wait(stl_critical_section_win7* lock) { + if (!wait_for(lock, INFINITE)) { std::terminate(); } } - bool wait_for(stl_critical_section_interface* lock, unsigned int timeout) override { - return SleepConditionVariableSRW(&m_condition_variable, - static_cast(lock)->native_handle(), timeout, 0) - != 0; + bool wait_for(stl_critical_section_win7* lock, unsigned int timeout) { + return SleepConditionVariableSRW(&m_condition_variable, lock->native_handle(), timeout, 0) != 0; } - void notify_one() override { + void notify_one() { WakeConditionVariable(&m_condition_variable); } - void notify_all() override { + void notify_all() { WakeAllConditionVariable(&m_condition_variable); } private: - CONDITION_VARIABLE m_condition_variable; + void* unused = nullptr; // TRANSITION, ABI: was the vptr + CONDITION_VARIABLE m_condition_variable = CONDITION_VARIABLE_INIT; }; - inline void create_stl_critical_section(stl_critical_section_interface* p) { + inline void create_stl_critical_section(stl_critical_section_win7* p) { new (p) stl_critical_section_win7; } - inline void create_stl_condition_variable(stl_condition_variable_interface* p) { + inline void create_stl_condition_variable(stl_condition_variable_win7* p) { new (p) stl_condition_variable_win7; } diff --git a/tests/std/tests/Dev11_1150223_shared_mutex/test.cpp b/tests/std/tests/Dev11_1150223_shared_mutex/test.cpp index 44ca1f2b6f..4a5ecdf278 100644 --- a/tests/std/tests/Dev11_1150223_shared_mutex/test.cpp +++ b/tests/std/tests/Dev11_1150223_shared_mutex/test.cpp @@ -58,10 +58,7 @@ STATIC_ASSERT(noexcept(declval().native_handle())); #if _HAS_CXX20 STATIC_ASSERT(noexcept(declval().native_handle())); #endif // _HAS_CXX20 -STATIC_ASSERT(noexcept(declval().native_handle())); -STATIC_ASSERT(noexcept(declval().native_handle())); STATIC_ASSERT(noexcept(declval().native_handle())); -STATIC_ASSERT(noexcept(declval().native_handle())); // Also test mandatory and strengthened exception specification for try_lock(). STATIC_ASSERT(noexcept(declval().try_lock())); // strengthened