// Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // global lock for locales, etc. #include #include #include #include "init_locks.hpp" #include "xmtx.hpp" _STD_BEGIN constexpr int _Max_lock = 8; // must be power of two; TRANSITION, ABI: may be less now #pragma warning(disable : 4074) #pragma init_seg(compiler) static _Rmtx mtx[_Max_lock]; static long init = -1; #if !defined(MRTDLL) __thiscall _Init_locks::_Init_locks() noexcept { // initialize locks if (InterlockedIncrement(&init) == 0) { for (auto& elem : mtx) { _Mtxinit(&elem); } } } __thiscall _Init_locks::~_Init_locks() noexcept { // clean up locks if (InterlockedDecrement(&init) < 0) { for (auto& elem : mtx) { _Mtxdst(&elem); } } } #endif // ^^^ !defined(MRTDLL) ^^^ void __cdecl _Init_locks::_Init_locks_ctor(_Init_locks*) noexcept { // initialize locks if (InterlockedIncrement(&init) == 0) { for (auto& elem : mtx) { _Mtxinit(&elem); } } } void __cdecl _Init_locks::_Init_locks_dtor(_Init_locks*) noexcept { // clean up locks if (InterlockedDecrement(&init) < 0) { for (auto& elem : mtx) { _Mtxdst(&elem); } } } static _Init_locks initlocks; #if !defined(MRTDLL) __thiscall _Lockit::_Lockit() noexcept : _Locktype(0) { // lock default mutex if (_Locktype == _LOCK_LOCALE) { _lock_locales(); } else { _Mtxlock(&mtx[0]); } } __thiscall _Lockit::_Lockit(int kind) noexcept : _Locktype(kind) { // lock the mutex if (_Locktype == _LOCK_LOCALE) { _lock_locales(); } else if (_Locktype < _Max_lock) { _Mtxlock(&mtx[_Locktype]); } } __thiscall _Lockit::~_Lockit() noexcept { // unlock the mutex if (_Locktype == _LOCK_LOCALE) { _unlock_locales(); } else if (_Locktype < _Max_lock) { _Mtxunlock(&mtx[_Locktype]); } } #endif // ^^^ !defined(MRTDLL) ^^^ void __cdecl _Lockit::_Lockit_ctor(_Lockit*) noexcept { // lock default mutex _Mtxlock(&mtx[0]); } void __cdecl _Lockit::_Lockit_ctor(_Lockit* _This, int kind) noexcept { // lock the mutex if (kind == _LOCK_LOCALE) { _lock_locales(); } else { _This->_Locktype = kind & (_Max_lock - 1); _Mtxlock(&mtx[_This->_Locktype]); } } void __cdecl _Lockit::_Lockit_dtor(_Lockit* _This) noexcept { // unlock the mutex _Mtxunlock(&mtx[_This->_Locktype]); } _RELIABILITY_CONTRACT void __cdecl _Lockit::_Lockit_ctor(int kind) noexcept { // lock the mutex if (kind == _LOCK_LOCALE) { _lock_locales(); } else { _Mtxlock(&mtx[kind & (_Max_lock - 1)]); } } _RELIABILITY_CONTRACT void __cdecl _Lockit::_Lockit_dtor(int kind) noexcept { // unlock the mutex if (kind == _LOCK_LOCALE) { _unlock_locales(); } else { _Mtxunlock(&mtx[kind & (_Max_lock - 1)]); } } _STD_END