зеркало из https://github.com/microsoft/STL.git
`<condition_variable>`: Avoid squirrelly forward declaration of `_Cnd_internal_imp_t` (#4545)
This commit is contained in:
Родитель
d3c435b3d1
Коммит
29b30dfb3b
|
@ -33,50 +33,38 @@ struct _Stl_critical_section {
|
|||
};
|
||||
|
||||
struct _Mtx_internal_imp_t {
|
||||
#if defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT)
|
||||
#ifdef _WIN64
|
||||
static constexpr size_t _Critical_section_size = 16;
|
||||
#else // ^^^ defined(_WIN64) / !defined(_WIN64) vvv
|
||||
static constexpr size_t _Critical_section_size = 8;
|
||||
#endif // ^^^ !defined(_WIN64) ^^^
|
||||
#else // ^^^ Windows private STL / public STL vvv
|
||||
#ifdef _WIN64
|
||||
#if defined(_CRT_WINDOWS) || defined(UNDOCKED_WINDOWS_UCRT) // for Windows-internal code
|
||||
static constexpr size_t _Critical_section_size = 2 * sizeof(void*);
|
||||
#elif defined(_WIN64) // ordinary 64-bit code
|
||||
static constexpr size_t _Critical_section_size = 64;
|
||||
#else // ^^^ defined(_WIN64) / !defined(_WIN64) vvv
|
||||
#else // vvv ordinary 32-bit code vvv
|
||||
static constexpr size_t _Critical_section_size = 36;
|
||||
#endif // ^^^ !defined(_WIN64) ^^^
|
||||
#endif // ^^^ public STL ^^^
|
||||
|
||||
static constexpr size_t _Critical_section_align = alignof(void*);
|
||||
#endif // ^^^ ordinary 32-bit code ^^^
|
||||
|
||||
int _Type{};
|
||||
union {
|
||||
_Stl_critical_section _Critical_section{};
|
||||
_STD _Aligned_storage_t<_Critical_section_size, _Critical_section_align> _Cs_storage;
|
||||
_STD _Aligned_storage_t<_Critical_section_size, alignof(void*)> _Cs_storage;
|
||||
};
|
||||
long _Thread_id{};
|
||||
int _Count{};
|
||||
};
|
||||
|
||||
// Size and alignment for _Cnd_internal_imp_t
|
||||
#if defined(_CRT_WINDOWS) // for Windows-internal code
|
||||
_INLINE_VAR constexpr size_t _Cnd_internal_imp_size = 2 * sizeof(void*);
|
||||
#elif defined(_WIN64) // ordinary 64-bit code
|
||||
_INLINE_VAR constexpr size_t _Cnd_internal_imp_size = 72;
|
||||
#else // vvv ordinary 32-bit code vvv
|
||||
_INLINE_VAR constexpr size_t _Cnd_internal_imp_size = 40;
|
||||
#endif // ^^^ ordinary 32-bit code ^^^
|
||||
|
||||
_INLINE_VAR constexpr size_t _Cnd_internal_imp_alignment = alignof(void*);
|
||||
|
||||
using _Mtx_t = _Mtx_internal_imp_t*;
|
||||
|
||||
#ifdef _M_CEE // avoid warning LNK4248: unresolved typeref token for '_Cnd_internal_imp_t'; image may not run
|
||||
using _Cnd_t = void*;
|
||||
#else // ^^^ defined(_M_CEE) / !defined(_M_CEE) vvv
|
||||
struct _Cnd_internal_imp_t;
|
||||
struct _Cnd_internal_imp_t {
|
||||
#if defined(_CRT_WINDOWS) // for Windows-internal code
|
||||
static constexpr size_t _Cnd_internal_imp_size = 2 * sizeof(void*);
|
||||
#elif defined(_WIN64) // ordinary 64-bit code
|
||||
static constexpr size_t _Cnd_internal_imp_size = 72;
|
||||
#else // vvv ordinary 32-bit code vvv
|
||||
static constexpr size_t _Cnd_internal_imp_size = 40;
|
||||
#endif // ^^^ ordinary 32-bit code ^^^
|
||||
|
||||
_STD _Aligned_storage_t<_Cnd_internal_imp_size, alignof(void*)> _Cv_storage;
|
||||
};
|
||||
|
||||
using _Cnd_t = _Cnd_internal_imp_t*;
|
||||
#endif // ^^^ !defined(_M_CEE) ^^^
|
||||
} // extern "C"
|
||||
|
||||
#pragma pop_macro("new")
|
||||
|
|
|
@ -220,10 +220,10 @@ public:
|
|||
private:
|
||||
shared_ptr<mutex> _Myptr;
|
||||
|
||||
_Aligned_storage_t<_Cnd_internal_imp_size, _Cnd_internal_imp_alignment> _Cnd_storage;
|
||||
_Cnd_internal_imp_t _Cnd_storage;
|
||||
|
||||
_NODISCARD _Cnd_t _Mycnd() noexcept { // get pointer to _Cnd_internal_imp_t inside _Cnd_storage
|
||||
return reinterpret_cast<_Cnd_t>(&_Cnd_storage);
|
||||
_NODISCARD _Cnd_t _Mycnd() noexcept {
|
||||
return &_Cnd_storage;
|
||||
}
|
||||
|
||||
template <class _Lock>
|
||||
|
|
|
@ -637,10 +637,10 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
_Aligned_storage_t<_Cnd_internal_imp_size, _Cnd_internal_imp_alignment> _Cnd_storage;
|
||||
_Cnd_internal_imp_t _Cnd_storage;
|
||||
|
||||
_Cnd_t _Mycnd() noexcept { // get pointer to _Cnd_internal_imp_t inside _Cnd_storage
|
||||
return reinterpret_cast<_Cnd_t>(&_Cnd_storage);
|
||||
_Cnd_t _Mycnd() noexcept {
|
||||
return &_Cnd_storage;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ extern "C" {
|
|||
|
||||
|
||||
_CRTIMP2_PURE void __cdecl _Cnd_init_in_situ(const _Cnd_t cond) noexcept { // initialize condition variable in situ
|
||||
new (cond->_get_cv()) Concurrency::details::stl_condition_variable_win7;
|
||||
new (Concurrency::details::_Get_cond_var(cond)) Concurrency::details::stl_condition_variable_win7;
|
||||
}
|
||||
|
||||
_CRTIMP2_PURE void __cdecl _Cnd_destroy_in_situ(_Cnd_t) noexcept {} // destroy condition variable in situ
|
||||
|
@ -54,7 +54,7 @@ _CRTIMP2_PURE void __cdecl _Mtx_reset_owner(_Mtx_t mtx) noexcept { // set owner
|
|||
_CRTIMP2_PURE _Thrd_result __cdecl _Cnd_wait(const _Cnd_t cond, const _Mtx_t mtx) noexcept { // wait until signaled
|
||||
const auto cs = &mtx->_Critical_section;
|
||||
_Mtx_clear_owner(mtx);
|
||||
cond->_get_cv()->wait(cs);
|
||||
Concurrency::details::_Get_cond_var(cond)->wait(cs);
|
||||
_Mtx_reset_owner(mtx);
|
||||
return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds
|
||||
}
|
||||
|
@ -66,13 +66,14 @@ _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_timedwait(
|
|||
const auto cs = &mtx->_Critical_section;
|
||||
if (target == nullptr) { // no target time specified, wait on mutex
|
||||
_Mtx_clear_owner(mtx);
|
||||
cond->_get_cv()->wait(cs);
|
||||
Concurrency::details::_Get_cond_var(cond)->wait(cs);
|
||||
_Mtx_reset_owner(mtx);
|
||||
} else { // target time specified, wait for it
|
||||
_timespec64 now;
|
||||
_Timespec64_get_sys(&now);
|
||||
_Mtx_clear_owner(mtx);
|
||||
if (!cond->_get_cv()->wait_for(cs, _Xtime_diff_to_millis2(target, &now))) { // report timeout
|
||||
if (!Concurrency::details::_Get_cond_var(cond)->wait_for(
|
||||
cs, _Xtime_diff_to_millis2(target, &now))) { // report timeout
|
||||
_Timespec64_get_sys(&now);
|
||||
if (_Xtime_diff_to_millis2(target, &now) == 0) {
|
||||
res = _Thrd_result::_Timedout;
|
||||
|
@ -84,12 +85,12 @@ _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_timedwait(
|
|||
}
|
||||
|
||||
_CRTIMP2_PURE _Thrd_result __cdecl _Cnd_signal(const _Cnd_t cond) noexcept { // release one waiting thread
|
||||
cond->_get_cv()->notify_one();
|
||||
Concurrency::details::_Get_cond_var(cond)->notify_one();
|
||||
return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds
|
||||
}
|
||||
|
||||
_CRTIMP2_PURE _Thrd_result __cdecl _Cnd_broadcast(const _Cnd_t cond) noexcept { // release all waiting threads
|
||||
cond->_get_cv()->notify_all();
|
||||
Concurrency::details::_Get_cond_var(cond)->notify_all();
|
||||
return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <__msvc_threads_core.hpp>
|
||||
#include <cstdlib>
|
||||
#include <type_traits>
|
||||
|
||||
|
@ -43,18 +44,8 @@ namespace Concurrency {
|
|||
CONDITION_VARIABLE m_condition_variable = CONDITION_VARIABLE_INIT;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline stl_condition_variable_win7* _Get_cond_var(::_Cnd_internal_imp_t* _Cond) noexcept {
|
||||
return reinterpret_cast<stl_condition_variable_win7*>(&_Cond->_Cv_storage);
|
||||
}
|
||||
} // namespace details
|
||||
} // namespace Concurrency
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct _Cnd_internal_imp_t {
|
||||
std::_Aligned_storage_t<_Cnd_internal_imp_size, _Cnd_internal_imp_alignment> cv;
|
||||
|
||||
[[nodiscard]] Concurrency::details::stl_condition_variable_win7* _get_cv() noexcept {
|
||||
// get pointer to implementation
|
||||
return reinterpret_cast<Concurrency::details::stl_condition_variable_win7*>(&cv);
|
||||
}
|
||||
};
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
@ -50,7 +50,7 @@ _Thrd_result __stdcall _Cnd_timedwait_for(const _Cnd_t cond, const _Mtx_t mtx, c
|
|||
mtx->_Thread_id = -1;
|
||||
--mtx->_Count;
|
||||
|
||||
if (!cond->_get_cv()->wait_for(cs, target_ms)) { // report timeout
|
||||
if (!Concurrency::details::_Get_cond_var(cond)->wait_for(cs, target_ms)) { // report timeout
|
||||
const auto end_ms = GetTickCount64();
|
||||
if (end_ms - start_ms >= target_ms) {
|
||||
res = _Thrd_result::_Timedout;
|
||||
|
|
Загрузка…
Ссылка в новой задаче