<mutex>注释 10: vs2019 c++20 规范,本头文件的全部源码以及源文件

(45) 本头文件的全部源码 ,很长,作为前面的汇总,共 1100 行:

// mutex standard header

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#pragma once

#ifndef _MUTEX_
#define _MUTEX_

#include <yvals_core.h>

#if _STL_COMPILER_PREPROCESSOR

#ifdef _M_CEE_PURE
#error <mutex> is not supported when compiling with /clr:pure.
#endif // _M_CEE_PURE
// 以上说明定义了宏  _M_CEE_PURE 就报错,不编译了

#include <__msvc_chrono.hpp>
#include <cstdlib>
#include <system_error>
#include <thread>
#include <utility>
#include <xcall_once.h>

#pragma pack(push, _CRT_PACKING)
// 以下的结构体以及 union 将采用 8 字节对齐。入栈原来的对齐方式 _CRT_PACKING = 8

#pragma warning(push, _STL_WARNING_LEVEL)
// 调整本源文件编译时候的警告级别,是较减少了警告。 _STL_WARNING_LEVEL = 3
// 0 不警告,4 全警告。并把原来的警告级别入栈

#pragma warning(disable : _STL_DISABLED_WARNINGS)
// #define  _STL_DISABLED_WARNINGS  4180 4412 4455 4494 4514 4574 ......
// 表示禁用这些警告,忽略这些警告 <yvals_core.h>

_STL_DISABLE_CLANG_WARNINGS
// 按字面意思,禁止 clang 警告,最后还有对应的 宏定义,_STL_RESTORE_CLANG_WARNINGS

#pragma push_macro("new")
#undef new
// 入栈系统之前的 new 的宏定义,并取消此宏定义。可能要自己定义内存管理方式

_STD_BEGIN
// #define _STD_BEGIN namespace std {  表示以下内容全部定义于  std  命名空间

// mutex and recursive_mutex are not supported under /clr 
// 在 /clr 下不支持互斥体和 recursive_mutex 。 注意是 ifndef  才编译本文件
#ifndef _M_CEE
class condition_variable;
class condition_variable_any;

class _Mutex_base // base class for all mutex types 所有互斥类型的基类
{ 
private:
    friend condition_variable;
    friend condition_variable_any;

    char _Mtx_storage[80]; //这是一个简化定义,参考了内存对齐与数据量需求等方面

    // using _Mtx_t = struct _Mtx_internal_imp_t *;  返回值是一个指针
    _Mtx_t _Mymtx() { return reinterpret_cast<_Mtx_t>(&_Mtx_storage); }

public:
    // enum { _Mtx_plain=0x01, _Mtx_try=0x02, _Mtx_timed=0x04, _Mtx_recursive=0x100 };
    //           mutex : _Mutex_base {           mutex() : _Mutex_base(                ) {} };
    // recursive_mutex : _Mutex_base { recursive_mutex() : _Mutex_base( _Mtx_recursive ) {} };
    _Mutex_base(int _Flags = 0) noexcept                 // 默认的父类构造函数
    {   // 可见,所有 mutex 互斥量默认具有 2_Mtx_try 标志 
        _Mtx_init_in_situ(_Mymtx(), _Flags | _Mtx_try);  // 底层函数使用了 pthread 库的实现为例
    }   // int pthread_mutex_init ( pthread_mutex_t * mutex , pthread_mutexattr_t * attr);

    // int pthread_mutex_destroy ( pthread_mutex_t * mutex );
    ~_Mutex_base() { _Mtx_destroy_in_situ( _Mymtx() ); } // 析构函数,调用了底层的销毁互斥量的函数

    _Mutex_base(const _Mutex_base&) = delete;            // 禁止 copy 构造函数
    _Mutex_base& operator=(const _Mutex_base&) = delete; // 禁止 copy 赋值运算符函数

    // 当函 _Mtx_lock(...) 返 _Thrd_success 时才不报错
    // int pthread_mutex_lock ( pthread_mutex_t * mutex ) ;
    void lock() {    _Check_C_return(  _Mtx_lock( _Mymtx() )  );     }

    // 函  _Mtx_unlock( _Mtx_t ) 总返回 _Thrd_success
    // int pthread_mutex_unlock ( pthread_mutex_t * mutex ) ;  
    void unlock() {    _Mtx_unlock(  _Mymtx()  );    }

    // enum { _Thrd_success, _Thrd_nomem, _Thrd_timedout, _Thrd_busy, _Thrd_error };
    bool try_lock()  
    {   // int __cdecl _Mtx_trylock( _Mtx_t );
        const auto _Res = _Mtx_trylock(  _Mymtx()  );

        switch (_Res) { // 只可以加锁成功或忙碌,否则报错终止进程。
        case _Thrd_success:     return true;
        case _Thrd_busy   :     return false;
        default           :     _Throw_C_error( _Res ); // 报错,终止进程
        }
    }

    using native_handle_type = void* ; // void* __cdecl _Mtx_getconcrtcs( _Mtx_t ); 
    native_handle_type native_handle() {   return _Mtx_getconcrtcs(  _Mymtx()  );  }
};

// mutex 与其父类 _Mutex_base 一模一样,没有做任何功能上的增加删除
class mutex : public _Mutex_base  
{ 
public:
    mutex() : _Mutex_base() {}
    mutex(const mutex&) = delete;   // 禁止了 copy 构造与 copy 赋值运算符函数
    mutex& operator=(const mutex&) = delete;
};

// class for recursive mutual exclusion 递归互斥的类,
class recursive_mutex : public _Mutex_base  // 从源代码看,未对基类 _Mutex_base 做任何功能扩展
{   // 可在同一个线程里对一个锁多次加锁
public:
    recursive_mutex() : _Mutex_base(_Mtx_recursive) {}

    recursive_mutex(const recursive_mutex&) = delete;  // 禁止了 copy 构造与 copy 赋值运算符函数
    recursive_mutex& operator=(const recursive_mutex&) = delete;

    bool try_lock() noexcept { return _Mutex_base::try_lock(); }
};

template <class _Mutex>
class lock_guard  // class with destructor that unlocks a mutex
{
private:
    _Mutex& _MyMutex;
public:
    using mutex_type = _Mutex;

    // construct and lock  在创建本 lock_guard 类型变量的时候,直接给上锁 
    explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { _MyMutex.lock(); }
    
    // 构造函数的重载
    lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) {} // construct but don't lock

    ~lock_guard() { _MyMutex.unlock(); } // 出了本类型变量的作用域,析构函数中自动解锁

    lock_guard(const lock_guard&) = delete; // 禁止的 copy 构造与 copy 赋值运算符函数
    lock_guard& operator=(const lock_guard&) = delete;
};
#endif // _M_CEE

// indicates adopt lock 指示采用锁,具有此标志的构造函数将不再给 mutex 加锁
struct adopt_lock_t  { explicit adopt_lock_t() = default; };

// indicates defer lock  指示延迟锁定
struct defer_lock_t  { explicit defer_lock_t() = default; };

// indicates try to lock
struct try_to_lock_t {  explicit try_to_lock_t() = default; };

_INLINE_VAR constexpr  adopt_lock_t   adopt_lock  {} ;
_INLINE_VAR constexpr  defer_lock_t   defer_lock  {} ;
_INLINE_VAR constexpr  try_to_lock_t  try_to_lock {} ;

//**************************************************************************************************

// _Mutex 可以是 mutex 或 timed_mutex , 但不可以是递归锁。本模板禁止重复加锁。
// whizzy class with destructor that unlocks mutex 具有解锁 Mutex 的析构函数的奇特类
template <class _Mutex>   
class unique_lock 
{ 
private:
    _Mutex* _Pmtx;   // 数据成员是一个互斥量的地址,类似智能指针
    bool    _Owns;   // 互斥量是否已被上锁,这是个 布尔量

    void _Validate() const  // check if the mutex can be locked测试是否可以加锁
    {
        if (!_Pmtx)  // 本 unique_lock 没有管理到锁
            _Throw_system_error(errc::operation_not_permitted);

        if (_Owns)   // 若互斥量已被上锁,则报错
            _Throw_system_error(errc::resource_deadlock_would_occur);
    }
public:
    using mutex_type = _Mutex;

    unique_lock() noexcept : _Pmtx(nullptr), _Owns(false) {} // 默认的无参构造函数

    explicit unique_lock(_Mutex& _Mtx) : // 有参构造函数 construct and lock 
        _Pmtx(_STD addressof(_Mtx)), _Owns(false) 
    {   
        _Pmtx->lock();
        _Owns = true;
    }

    ~unique_lock() noexcept { if (_Owns)  _Pmtx->unlock(); } // 析构函数

    // construct and assume already locked  有参构造函数
    unique_lock(_Mutex& _Mtx, adopt_lock_t) : _Pmtx(_STD addressof(_Mtx)), _Owns(true) {}

    // construct but don't lock             有参构造函数
    unique_lock(_Mutex& _Mtx, defer_lock_t) : _Pmtx(_STD addressof(_Mtx)), _Owns(false) {} 

    // construct and try to lock            有参构造函数,尝试加一次锁
    unique_lock(_Mutex& _Mtx, try_to_lock_t): _Pmtx(_STD addressof(_Mtx)), _Owns(_Pmtx->try_lock()) {} 
    /*
    class _Mutex_base // base class for all mutex types 所有互斥类型的基类
    {
        aligned_storage_t<_Mtx_internal_imp_size, _Mtx_internal_imp_alignment> _Mtx_storage;

        bool try_lock()  // enum { _Thrd_success, _Thrd_nomem, _Thrd_timedout, _Thrd_busy, _Thrd_error };
        {
            // int __cdecl _Mtx_trylock(_Mtx_t);
            const auto _Res = _Mtx_trylock(_Mymtx());

            switch (_Res)
            {
            case _Thrd_success:     return true;
            case _Thrd_busy:        return false;
            default:                _Throw_C_error(_Res);
            }
        }
    };
    */

    unique_lock(const unique_lock&) = delete;            // 禁止了 copy 构造函数
    unique_lock& operator=(const unique_lock&) = delete; // 禁止了 copy 赋值运算符函数

    unique_lock(unique_lock&& _Other) noexcept     // 移动构造函数
        : _Pmtx(_Other._Pmtx), _Owns(_Other._Owns)
    {
        _Other._Pmtx = nullptr;
        _Other._Owns = false;
    }

    unique_lock& operator=(unique_lock&& _Other)  // 移动赋值运算符函数
    {
        if (this != _STD addressof(_Other))
        {   // 若本 unique_lock 管理的互斥量已被上锁,先解锁
            if (_Owns)     _Pmtx->unlock();

            _Pmtx = _Other._Pmtx;
            _Owns = _Other._Owns;
            _Other._Pmtx = nullptr;
            _Other._Owns = false;
        }

        return *this;
    }

    // 当互斥量存在且未被锁定,函 _Validate() 才不会报错
    // 对本 unique_lock 管理的互斥量, 上锁   
    void lock    () { _Validate();              _Pmtx->lock();  _Owns = true; }

    // 对本 unique_lock 管理的互斥量, try 尝试上锁
    bool try_lock() { _Validate();  _Owns = _Pmtx->try_lock();  return _Owns; }

    void unlock()
    {
        if (!_Pmtx || !_Owns) // 若不存在互斥量,或存在但未被锁定,报错
            _Throw_system_error(errc::operation_not_permitted);

        _Pmtx->unlock();
        _Owns = false;
    }

    void swap(unique_lock& _Other) noexcept
    {
        _STD swap(_Pmtx, _Other._Pmtx);
        _STD swap(_Owns, _Other._Owns);
    }

    _Mutex* mutex() const noexcept { return _Pmtx; }

    _Mutex* release() noexcept  // 返回互斥量的裸指针,但未释放锁
    {                           // release ,释放,不再管理此互斥量
        _Mutex* _Res = _Pmtx;
        _Pmtx = nullptr;
        _Owns = false;
        return _Res;
    }

    bool owns_lock() const { return _Owns; } // 若互斥量已被加锁,则返回 true

    explicit operator bool() const { return _Owns; } // 类型转换运算符,返回是否上了锁

    // 模板参数 _Mutex 须是 timed_mutex 或 recursive_timed_mutex 类型。带时间的构造函数
    unique_lock(_Mutex& _Mtx, const xtime* _Abs_time) : _Pmtx(_STD addressof(_Mtx)), _Owns(false)
    {
        _Owns = _Pmtx->try_lock_until(_Abs_time);    // try to lock until _Abs_time
    }

    template <class _Clock, class _Duration>         // 有参构造函数,形参是 time_point 类型
    unique_lock(_Mutex& _Mtx, const chrono::time_point<_Clock, _Duration>& _Abs_time)
        : _Pmtx(_STD addressof(_Mtx)), _Owns(_Pmtx->try_lock_until(_Abs_time))
    {
#if _HAS_CXX20
        static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
    }

    template <class _Rep, class _Period>    // construct and lock with timeout
    unique_lock(_Mutex& _Mtx, const chrono::duration<_Rep, _Period>& _Rel_time) // 形参是时间段
        : _Pmtx(_STD addressof(_Mtx)), _Owns(_Pmtx->try_lock_for(_Rel_time)) {} 

    bool try_lock_until(const xtime* _Abs_time) // 限时加锁的成员函数
    {
        _Validate();
        _Owns = _Pmtx->try_lock_until(_Abs_time);
        return _Owns;
    }

    template <class _Clock, class _Duration>
    bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time)
    {
#if _HAS_CXX20
        static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
        _Validate();
        _Owns = _Pmtx->try_lock_until(_Abs_time);
        return _Owns;
    }

    // 核心是调用被 unique_lock 封装的 _Mutex . try_lock_for()
    template <class _Rep, class _Period>  
    bool try_lock_for(const chrono::duration<_Rep, _Period>& _Rel_time) 
    {   
        _Validate();
        _Owns = _Pmtx->try_lock_for(_Rel_time);
        return _Owns;
    }

};

template <class _Mutex>  // 全局函数
void swap(unique_lock<_Mutex>& _Left, unique_lock<_Mutex>& _Right) noexcept 
{
    _Left.swap(_Right);
}

//****************************************************************************

template <size_t... _Indices, class... _LockN> // 这部分复杂的先暂时不看了
void _Lock_from_locks(const int _Target, index_sequence<_Indices...>, _LockN&... _LkN)  // lock _LkN[_Target]
{
    int _Ignored[] = {(
        (static_cast<int>(_Indices) == _Target ? 
                            (void) _LkN.lock() :
                                          void()
            ), 0
        )...};
    (void) _Ignored;
}

template <size_t... _Indices, class... _LockN>
bool _Try_lock_from_locks(
    const int _Target, index_sequence<_Indices...>, _LockN&... _LkN) { // try to lock _LkN[_Target]
    bool _Result{};
    int _Ignored[] = {((static_cast<int>(_Indices) == _Target ? (void) (_Result = _LkN.try_lock()) : void()), 0)...};
    (void) _Ignored;
    return _Result;
}

template <size_t... _Indices, class... _LockN>
void _Unlock_locks(const int _First, const int _Last, index_sequence<_Indices...>, _LockN&... _LkN) noexcept
/* terminates */ {
    // unlock locks in _LkN[_First, _Last)
    int _Ignored[] = {
        ((_First <= static_cast<int>(_Indices) && static_cast<int>(_Indices) < _Last ? (void) _LkN.unlock() : void()),
            0)...};
    (void) _Ignored;
}

template <class... _LockN>
int _Try_lock_range(const int _First, const int _Last, _LockN&... _LkN) 
{
    using _Indices = index_sequence_for<_LockN...>;
    int _Next      = _First;
    _TRY_BEGIN
    for (; _Next != _Last; ++_Next) 
        if (!_Try_lock_from_locks(_Next, _Indices{}, _LkN...))  // try_lock failed, backout
        { 
            _Unlock_locks(_First, _Next, _Indices{}, _LkN...);
            return _Next;
        }
    _CATCH_ALL
    _Unlock_locks(_First, _Next, _Indices{}, _LkN...);
    _RERAISE;
    _CATCH_END

    return -1;
}

template <class _Lock0, class _Lock1, class _Lock2, class... _LockN>
int _Try_lock1(_Lock0& _Lk0, _Lock1& _Lk1, _Lock2& _Lk2, _LockN&... _LkN) 
{   // try to lock 3 or more locks
    return _Try_lock_range(0, sizeof...(_LockN) + 3, _Lk0, _Lk1, _Lk2, _LkN...);
}

template <class _Lock0, class _Lock1>  // 函数的重载
int _Try_lock1(_Lock0& _Lk0, _Lock1& _Lk1) 
{
    if (!_Lk0.try_lock())  // 此函数 try 加锁成功则返回 true,锁忙碌则返回 false
        return 0;

    _TRY_BEGIN              // try {
    if (!_Lk1.try_lock()) { //     if (!_Lk1.try_lock()) { 
        _Lk0.unlock();      //          _Lk0.unlock();
        return 1;           //          return 1;
    }                       //     }
    _CATCH_ALL              // } catch (...) { // 也可能没有错误,捕捉不到错误,不需终止进程
        _Lk0.unlock();      //     _Lk0.unlock();
    _RERAISE;               //     throw;
    _CATCH_END              // }

    return -1;
}

template <class _Lock0, class _Lock1, class... _LockN>
int try_lock(_Lock0& _Lk0, _Lock1& _Lk1, _LockN&... _LkN)
{   // try to lock multiple locks
    return _Try_lock1(_Lk0, _Lk1, _LkN...);
}   // 本函尝试加锁成功,返回 -1 。锁忙碌则释放所有的锁,返回0 或 1

//*******************************************************************************************

/*
template <class _Lock0, class _Lock1, class _Lock2, class... _LockN> // lock 3 or more locks, without deadlock
void _Lock_nonmember1(_Lock0& _Lk0, _Lock1& _Lk1, _Lock2& _Lk2, _LockN&... _LkN)
{   
    int _Hard_lock = 0;
    while (_Hard_lock != -1) 
        _Hard_lock = _Lock_attempt(_Hard_lock, _Lk0, _Lk1, _Lk2, _LkN...);
}
*/
template <class... _LockN> // 该函数不看了,所有注释也一并保留
int _Lock_attempt(const int _Hard_lock, _LockN&... _LkN) 
{   // attempt to lock 3 or more locks, starting by locking _LkN[_Hard_lock] and trying to lock the rest
    
    using _Indices = index_sequence_for<_LockN...>;
/*
template <class _Ty, _Ty... _Vals>   // sequence of integer parameters
struct integer_sequence { 	using value_type = _Ty;  };

template <class _Ty, _Ty _Size>
using make_integer_sequence = __make_integer_seq<integer_sequence, _Ty, _Size>;

template <size_t _Size>
using make_index_sequence = make_integer_sequence<size_t, _Size>;

template <class... _Types>
using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
*/
    _Lock_from_locks(_Hard_lock, _Indices{}, _LkN...);
/*
template <size_t... _Indices, class... _LockN>
void _Lock_from_locks(const int _Target, index_sequence<_Indices...>, _LockN&... _LkN)  // lock _LkN[_Target]
{
    int _Ignored[] = {(
        (static_cast<int>(_Indices) == _Target ?
                            (void) _LkN.lock() :
                                          void()
            ), 0
        )...};

    (void) _Ignored;
}
*/
    int _Failed        = -1;
    int _Backout_start = _Hard_lock; // that is, unlock _Hard_lock

    _TRY_BEGIN
    _Failed = _Try_lock_range(0, _Hard_lock, _LkN...);
/*
template <class... _LockN>
int _Try_lock_range(const int _First, const int _Last, _LockN&... _LkN)
{
    using _Indices = index_sequence_for<_LockN...>;
    int _Next      = _First;
    _TRY_BEGIN
    for (; _Next != _Last; ++_Next)
        if (!_Try_lock_from_locks(_Next, _Indices{}, _LkN...))  // try_lock failed, backout
        {
            _Unlock_locks(_First, _Next, _Indices{}, _LkN...);
            return _Next;
        }
    _CATCH_ALL
    _Unlock_locks(_First, _Next, _Indices{}, _LkN...);
    _RERAISE;
    _CATCH_END

    return -1;
}
*/
    if (_Failed == -1)
    {
        _Backout_start = 0; // that is, unlock [0, _Hard_lock] if the next throws
        _Failed        = _Try_lock_range(_Hard_lock + 1, sizeof...(_LockN), _LkN...);
        if (_Failed == -1)  // we got all the locks
            return -1;
    }
    _CATCH_ALL
    _Unlock_locks(_Backout_start, _Hard_lock + 1, _Indices{}, _LkN...);
    _RERAISE;
    _CATCH_END

    // we didn't get all the locks, backout
    _Unlock_locks(_Backout_start, _Hard_lock + 1, _Indices{}, _LkN...);
    _STD this_thread::yield();
    return _Failed;
}


template <class _Lock0, class _Lock1> // 返回值的意思是,若加锁失败,则需要尝试重新加锁,故返回 true。
bool _Lock_attempt_small(_Lock0& _Lk0, _Lock1& _Lk1)  // 所以,若加锁成功则本函返回 false
{   // 尝试锁定2个锁,首先锁定_Lk0,然后尝试锁定_Lk1。返回是否再次trv
    // attempt to lock 2 locks, by first locking _Lk0, and then trying to lock _Lk1 
    // returns whether to try again。

    _Lk0.lock();
    _TRY_BEGIN           //  try {
    if (_Lk1.try_lock()) //     if (_Lk1.try_lock()) // 本函加锁成功返 T,锁忙碌返 F
        return false;    //         return false;

    _CATCH_ALL           //  } catch (...) {   // 也可能没有错误,捕捉不到错误,不需终止进程
    _Lk0.unlock();       //     _Lk0.unlock();
    _RERAISE;            //     throw;
    _CATCH_END           //  }

    _Lk0.unlock();       //  因为加锁失败,获得的 LK0 锁也释放掉
    _STD this_thread::yield(); // // 使本线程让出 CPU
    return true;         // true 表示本线程再次获得运行时需再次尝试获取这俩锁
}

template <class _Lock0, class _Lock1, class _Lock2, class... _LockN>
void _Lock_nonmember1(_Lock0& _Lk0, _Lock1& _Lk1, _Lock2& _Lk2, _LockN&... _LkN)
{   // 函数重载的复杂情况 lock 3 or more locks, without deadlock
    int _Hard_lock = 0;
    while (_Hard_lock != -1) 
        _Hard_lock = _Lock_attempt(_Hard_lock, _Lk0, _Lk1, _Lk2, _LkN...);
}

template <class _Lock0, class _Lock1> // 这是重载的简单情况
void _Lock_nonmember1(_Lock0& _Lk0, _Lock1& _Lk1)
{   // 锁 2 锁,没有死锁,特殊情况下更好的 codegen 和 redu 通用元编程
    while ( _Lock_attempt_small(_Lk0, _Lk1) && _Lock_attempt_small(_Lk1, _Lk0)) {}  
    // 函数 _Lock_attempt_small 加锁成功则返回 false ,加锁失败返回 true
}

template <class _Lock0, class _Lock1, class... _LockN> // lock multiple locks, without deadlock
void lock(_Lock0& _Lk0, _Lock1& _Lk1, _LockN&... _LkN) // 锁定多个锁,无死锁
{   //看源码,本函只有在获取了所有锁之后,才会返回。
    _Lock_nonmember1(_Lk0, _Lk1, _LkN...);
}   //本函数的实现灵魂是调用 mutex.try_lock(),该函数不会陷入睡眠等待


//***************************************************************************************************

#ifndef _M_CEE
#define _WINDOWS_API              __declspec(dllimport) __stdcall
#define _RENAME_WINDOWS_API(_Api) _Api
#endif // _M_CEE

extern "C"  int __std_init_once_begin_initialize(
    void** _LpInitOnce, unsigned long _DwFlags, int* _FPending, void** _LpContext) noexcept;

// 这两个系统函数都是成功执行返回 true,失败返回 false。 参数名可以见名知意。

// 系统函数__std_init_once_complete(&_Once._Opaque, 控制标志, 可选的上下文环境)
extern "C" int __std_init_once_complete(
     void** _LpInitOnce, unsigned long _DwFlags, void* _LpContext) noexcept;

// #define RTL_RUN_ONCE_INIT_FAILED    0x00000004UL
// #define INIT_ONCE_INIT_FAILED       RTL_RUN_ONCE_INIT_FAILED
_INLINE_VAR constexpr unsigned long _Init_once_init_failed = 0x4UL; // 初始化失败的标志

struct once_flag  // opaque不透明的 data structure for call_once()
{
    void* _Opaque; // 含有一个指针类型的数据成员

    once_flag() noexcept : _Opaque(nullptr) {} // 默认构造函数

    once_flag(const once_flag&) = delete;            // 禁止 copy 构造函数
    once_flag& operator=(const once_flag&) = delete; // 禁止 copy 赋值运算符函数
};

struct _Init_once_completer // 类似智能指针或 lock_guard,用于析构上面的 once_flag 对象
{                           // 本类型的对象是定义在 call_once(...) 函数内的局部对象
    once_flag& _Once;       // 数据成员,对 once_flag 类型的数据的引用
    unsigned long _DwFlags;

    ~_Init_once_completer() // 析构函数
    {   
        if ( __std_init_once_complete(&_Once._Opaque, _DwFlags, nullptr) == 0 ) 
            _CSTD abort();  // __declspec(noreturn) void __cdecl abort(void);
    }
};

// call_once(..) 全局函数,类的静态成员函数,类的可调用对象,都是可以的;
// 但不可以 call_once(...) 类的动态成员函数,因为无法传递对象本身这个参数。
// 在进程全局里生成 once_flag 对象,这里使用其 once_flag对象 的左值引用
template <class _Fn, class... _Args>  // call 函数  _Fx(_Ax...) once,只调用形参中的函数一次
void call_once (once_flag&  _Once, _Fn&& _Fx, _Args&&... _Ax)  // 这一行最重要
noexcept(noexcept(_STD invoke(_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...))) 
{
    int _Pending;

    // 看意思,函数仅可以被执行一次的设置,是在这里执行的,这里的 nullptr 也是可选的上下文环境
    if ( __std_init_once_begin_initialize(&_Once._Opaque, 0, &_Pending, nullptr) == 0 )
        _CSTD abort(); // __declspec(noreturn) void __cdecl abort(void);

    if (_Pending != 0) // unsigned long _Init_once_init_failed = 0x4UL; 
    {       
        _Init_once_completer _Op{_Once, _Init_once_init_failed}; // 本函数内定义的局部变量

        _STD invoke(_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...);
        _Op._DwFlags = 0;
    }
}

#undef _WINDOWS_API
#undef _RENAME_WINDOWS_API

//****************************************************************************************************

// condition_variable, timed_mutex, and recursive_timed_mutex are not supported under /clr
#ifndef _M_CEE 
// names for wait returns  , cv 含义是 condition_variable 啊
enum class cv_status {  no_timeout,   timeout  }; // 枚举类型
// 本枚举,只是为了区分线程被 nofity 唤醒且拿到锁以后,是没超时醒来,还是发生了超时,仅此而已。

class condition_variable  // class for waiting for conditions
{
private:
    char _Cnd_storage[72]; //这是一个简化定义,参考了内存对齐与数据量需求等方面

    // using _Mtx_t = struct _Mtx_internal_imp_t * ; 对于 mutex 也有类似的定义
    // using _Cnd_t = struct _Cnd_internal_imp_t * ; 缺乏该结构的具体定义,只有其指针
    // get pointer to _Cnd_internal_imp_t inside _Cnd_storage
    _Cnd_t _Mycnd() noexcept { return reinterpret_cast<_Cnd_t>(&_Cnd_storage); }

public:
    using native_handle_type = _Cnd_t; // 这是一个指针类型
    native_handle_type native_handle() { return _Mycnd() ; } // 返回本类的数据成员的地址

    // void __cdecl _Cnd_init_in_situ(_Cnd_t);    // 本类的构造函数,初始化本类的的数据成员
    // int pthread_cond_init ( pthread_cond_t * cond, pthread_condattr_t * attr ) ;
    condition_variable() {      _Cnd_init_in_situ( _Mycnd() );       }

    // void __cdecl _Cnd_destroy_in_situ(_Cnd_t); // 本类的析构函数,析构 本类的数据成员
    // int pthread_cond_destroy ( pthread_cond_t * cond ) ;
    ~condition_variable() noexcept  {   _Cnd_destroy_in_situ(_Mycnd());   }

    condition_variable(const condition_variable&) = delete;            // 禁止 copy 构造函数
    condition_variable& operator=(const condition_variable&) = delete; // 禁止 copy 赋值运算符函数

    // 函 _Cnd_signal(...) 总返回 _Thrd_success 。 // wake up one waiter 
    // int pthread_cond_signal ( pthread_cond_t * cond );    
    void notify_one() noexcept {   _Cnd_signal(  _Mycnd()  ) ;  }

    // 函 _Cnd_broadcast(...) 总返回 _Thrd_success 
    // wake up all waiters 将唤醒所有等待锁的线程,这些线程都有机会获取锁,以执行锁后面的代码
    // int pthread_cond_broadcast ( pthread_cond_t * cond ) ;   
    void notify_all() noexcept {   _Cnd_broadcast( _Mycnd() );  }

    // 线程退出时,会进行释放资源、更新状态或通知其他线程。
    // 这些操作常通过线程退出回调、析构函数(如果线程对象有的话)或特定的库函数来实现。
    // register this object for release at thread exit 注册此对象以便在线程退出时释放
    void _Register(unique_lock<mutex>& _Lck, int * _Ready)   
    {   // 在线程结束时,若形参 2 ready 不为 true, 则不再执行条件变量的唤醒操作
        // void __cdecl _Cnd_register_at_thread_exit(_Cnd_t, _Mtx_t, int*);
        _Cnd_register_at_thread_exit(  _Mycnd(), _Lck.release()->_Mymtx(), _Ready  );
    }
    // 这两个函数,服务于 async 、future 系列的线程调用。
    // unregister this object for release at thread exit 注销此对象以便在线程退出时释放
    void _Unregister(mutex& _Mtx) 
    {   // 功能上 _Unregister 似乎是对应于取消 _Register 的操作:不在线程结束时执行唤醒操作了
        // void __cdecl _Cnd_unregister_at_thread_exit(_Mtx_t);
        _Cnd_unregister_at_thread_exit(  _Mtx._Mymtx()  );
    }
/*
template <class _Ty>
class _Associated_state  //本类存储了线程中函数的返回值
{   // ready 初始化为 0 , 0 表还未 ready ,因函数还未执行
    int _Ready;   bool _Ready_at_thread_exit;   condition_variable _Cond;

    // 虚析构函数,其子类 _Packaged_state 与 孙类 _Deferred_async_state 都没明确定义的析构函数
    // 可见析构时,若符合线程退出才唤醒的条件,则需要打断 register 的施法,因为函数返回值已经不存在了
    virtual ~_Associated_state() { if (_Has_stored_result && !_Ready)   _Cond._Unregister(_Mtx); }

    virtual void _Do_notify(unique_lock<mutex>* _Lock, bool _At_thread_exit)
    {   // 此是虚函数,但从没有被改写过
        _Has_stored_result = true;

        if (_At_thread_exit)   _Cond._Register(*_Lock, &_Ready); // notify at thread exit
        else                 { _Ready = true;  _Cond.notify_all(); }
    }
};
*/

    // int pthread_cond_wait ( pthread_cond_t * cond , pthread_mutex_t * mutex ) ;
    // 函 _Cnd_wait(...) 总返回 _Thrd_success,故不用检查返回值。本函被下面的重载调用
    void wait(unique_lock<mutex>& _Lck) {  _Cnd_wait( _Mycnd(), _Lck.mutex()->_Mymtx() ); }

    // wait for signal and test predicate
    // wait() 被唤醒后,本线程需再次抢得锁;若断言条件不满足,就继续释放锁,睡眠等待。
    // 若 pred() 返回 F,则线程会释放互斥量,并堵塞在本行;若返 true,则线程继续往下执行。
    template <class _Predicate>  // 第二个参数是函数,例如 lamda 表达式,断言
    void wait(unique_lock<mutex>& _Lck, _Predicate _Pred) { while (!_Pred())  wait(_Lck); }

    //*****************************************

    // wait for signal with timeout  本函是 最基础,是最终被执行的函数!!,被别的成员函数调用
    // 经测试,即使使用了限时等待,若超时后,线程依然没有被 notify() 唤醒,还会继续超时睡眠;
    // 形参2 的时刻必须是相对于 1970 年的时刻,即使用 system_clock,而不能是 steady_clock 。
    // 直到被 notify() 唤醒,且再次拿到了锁。本函的返回值仅仅是提示线程被唤醒时是否发生了超时。
    cv_status wait_until(unique_lock<mutex>& _Lck, const xtime * _Abs_time) // !!
    {
        if (!_Mtx_current_owns(_Lck.mutex()->_Mymtx())) // 看起来是进入等待前要先持有锁
            _Throw_Cpp_error(_OPERATION_NOT_PERMITTED);

//int pthread_cond_timedwait ( pthread_cond_t* cond, pthread_mutex_t* mutex, timespec* abstime );
        const int _Res = _Cnd_timedwait(_Mycnd(), _Lck.mutex()->_Mymtx(), _Abs_time);//此函不会抛出异常

        // enum { _Thrd_success, _Thrd_nomem, _Thrd_timedout, _Thrd_busy, _Thrd_error };
        switch (_Res)
        {
        case _Thrd_success  :    return cv_status::no_timeout;
        case _Thrd_timedout :    return cv_status::timeout;
        default             :    _Throw_C_error(_Res);
        }
    }

    // enum class cv_status  {  no_timeout, timeout }; 
    // wait for duration ,转化为 调用 wait_until(unique_lock<mutex>& _Lck, const xtime* _Abs_time)
    template <class _Rep, class _Period>  // 如果在超时时间以外还没有收到唤醒通知,则线程会停止阻塞。
    cv_status wait_for(unique_lock<mutex>& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time)
    {   
        if ( _Rel_time <= chrono::duration<_Rep, _Period>::zero() ) 
            return cv_status::timeout; // 若形参 2为负值时间,本线程将不再进入睡眠状态,本函直接返回了

        _CSTD xtime _Tgt;  // struct xtime { long long sec ;	long nsec ; };

        // 本函的形参 2 是相对于当前时间的时间间隔,圆整成 10天内,相对于 1970年的绝对时刻,存入形参 1;
        // 若发生了时长截断,形参2 大于 10 天,则返回 true ,否则返回 false。形参一是左值引用。
        // template <class _Rep, class _Period> // int类型最大值 2,147,483,647 约等于 2*10^9 刚好够用
        // bool _To_xtime_10_day_clamped( xtime & _Xt, duration<_Rep, _Period> & _Rel_time )
        const bool _Clamped = _To_xtime_10_day_clamped(_Tgt, _Rel_time);

        const cv_status _Result = wait_until(_Lck, &_Tgt);  // 调用了上面注释里的成员函数

        if ( _Clamped )   return cv_status::no_timeout; //发生时间截断的线程唤醒,肯定是不会超时的

        return _Result;
    }

    // 这个函数与上面的是一组,都不带断言。没有收到唤醒信号,即使超时也要继续睡眠。
    template <class _Clock, class _Duration>  // wait until time point,有系统时钟与稳定时钟俩种
    cv_status wait_until(unique_lock<mutex>& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time)
    {
#if _HAS_CXX20
        static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
        for (;;)
        {
            const auto _Now = _Clock::now(); // 若形参 2是相对于当前时间的过去时,直接返回超时;
            if ( _Abs_time <= _Now )   return cv_status::timeout; // 本线程也将不再进入睡眠等待状态

            _CSTD xtime _Tgt; // _T_x_1_d_c(...)函把不同时钟里的时刻都转换为相对于 1970年 的绝对时间
            (void)_To_xtime_10_day_clamped( _Tgt , _Abs_time - _Now);

            const cv_status _Result = wait_until(_Lck, &_Tgt);  // 此行只在被 notify唤醒后才会返回

            if (_Result == cv_status::no_timeout)  return cv_status::no_timeout;//条件变量唤醒
        }
    }

    //*********************以下的函数带断言,以上的函数更简单些

private:
    // 未超时下的断言为假则继续睡眠等待直到断言为真; 超时后的条件唤醒则直接返回断言结果,断言为假也不再睡眠
    template <class _Predicate>   // wait for signal with timeout and check predicate
    bool _Wait_until1(unique_lock<mutex>& _Lck, const xtime* _Abs_time, _Predicate& _Pred)
    {
        while ( !_Pred() )
            if (wait_until(_Lck, _Abs_time) == cv_status::timeout) 
                return _Pred();

        return true;
    }

    // 本函数支持 10 天以上乃至更多天数的断言等待。每 10 天为一个睡眠周期,依次积累。
    template <class _Clock, class _Duration, class _Predicate> // 本函数的语义同上,没有变化
    bool _Wait_until1( unique_lock<mutex>& _Lck,   
        const chrono::time_point<_Clock, _Duration>& _Abs_time, _Predicate& _Pred)
    {
        while ( !_Pred() ) // 先断言一次。先拿到锁以后,再调用 wait_xx 系列的等待函数。
        {
            const auto _Now = _Clock::now(); // 若形参 2是历史时间则直接返回 false,不再睡眠
            if (_Abs_time <= _Now)   return false;

            _CSTD xtime _Tgt;
            const bool _Clamped = _To_xtime_10_day_clamped(_Tgt, _Abs_time - _Now);

            if (wait_until(_Lck, &_Tgt) == cv_status::timeout && !_Clamped) 
                return _Pred();        
        }

        return true;
    }

public:                          // public 以下的成员函数供外界使用
    template <class _Predicate>  // 这个重载函数最简单,未在私有的成员函数的基础上做任何语句增删
    bool wait_until(unique_lock<mutex>& _Lck, const xtime* _Abs_time, _Predicate _Pred)
    {
        return _Wait_until1(_Lck, _Abs_time, _Pred);
    }

    template <class _Clock, class _Duration, class _Predicate>  // 这个重载函数也很简单
    bool wait_until(unique_lock<mutex>& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time, _Predicate _Pred)
    {
#if _HAS_CXX20
        static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
        return _Wait_until1(_Lck, _Abs_time, _Pred);
    }

    // 函 _To_absolute_time 的返回值类型是 time_point <  steady_clock , duration<long_long,nano>  >
    // auto _To_absolute_time (const chrono::duration<_Rep, _Period>& _Rel_time ) 
    template <class _Rep, class _Period, class _Predicate>
    bool wait_for(unique_lock<mutex>& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time, _Predicate _Pred)
    {   // 等待信号,带有超时限制和断言 wait for signal with timeout and check predicate 
        return _Wait_until1(_Lck, _To_absolute_time(_Rel_time), _Pred);  
    }

};

//************************************************************************************************************

struct _UInt_is_zero // 本类是可调用对象,实现了括号运算符函数。
{
    const unsigned int& _UInt; // 数据成员是左值引用,看来是保存了一个整型数据

    bool operator()() const { return _UInt == 0; } // 括号运算符函数,数据为 0 则返回 true 
};

// 同时具有 mutex 和 condition_variable 的另一个类是 <future> 中的 保存函数返回值的 _Associated_state<_Ty>
// class for timed mutual exclusion 定时互斥的类 , 本类没有继承 _Mutex_base
class timed_mutex  // 同时结合了 mutex 与 condition_variable
{   // _My_locked 的含义是线程对锁加了几次锁。但本 timed_mutex 非递归锁,统计加锁次数无意义,故赋值为全 F。
private:                             // _My_locked 非 0 表已有线程抢占了临界资源 ;
    unsigned int        _My_locked ; // 此值为 0 表本线程可以占有临界资源,并修改本值为 非0 。
    mutex               _My_mutex  ; // 此处的 mutex 保护的是对数据成员 _My_locked 的访问的原子性
    condition_variable  _My_cond   ; // 为了实现线程同步, mutex 与条件变量总是同时使用、同时出现。
    
public:
    timed_mutex() noexcept : _My_locked(0) {}  // 默认的构造函数。没有显式定义的析构函数

    timed_mutex(const timed_mutex&) = delete;  // 禁止了 copy 构造函数
    timed_mutex& operator=(const timed_mutex&) = delete; // 禁止了 copy 赋值运算符

    void lock() // lock the mutex,但本函执行完毕时就释放了 mutex 。本类中的 mutex 成员大部分时间是空闲的。
    {           // 本成员函数只是独占地修改了数据成员 _My_locked 的值为 非零。
        unique_lock<mutex> _Lock(_My_mutex); // 此行代码的执行,隐含了对 mutex 的加锁成功。

        // 意思是即使拿到了锁,但若 _My_locked != 0 ,也要释放锁并等待唤醒。
        while ( _My_locked != 0 )     _My_cond.wait(_Lock); 
                          
        _My_locked = UINT_MAX; // UINT_MAX = 0xffffffff ,本线程拿到临界资源后就修改 _My_locked 为 非0
    }

    void unlock()  // unlock the mutex 本类的释放锁后,还有新的功能就是执行条件变量的唤醒。
    { 
        {   // template <class _Mutex>
            // class lock_guard { _Mutex& _MyMutex; ~lock_guard() { _MyMutex.unlock(); } };
            lock_guard<mutex> _Lock(_My_mutex);  // The lock here is necessary
            _My_locked = 0;  // 强制加锁,然后把  _My_locked 修改为 0 , 再释放锁
        }

        _My_cond.notify_one(); // 只唤醒一个等待的线程。
    }

    bool try_lock() noexcept // try to lock the mutex ,
    {   // 本函与 mutex.try_lock(...) 的实现不同,但语义还是相同的。 true 表加锁成功。
        lock_guard<mutex> _Lock(_My_mutex);   // 此行语句的执行,表示加锁成功
        if (_My_locked != 0)    return false; // 非 0,返 F,表别的线程在使用临界资源
        else {
            _My_locked = UINT_MAX ;
            return true;
        }
    }

    //******************************

    // 本函的语义是 : 在限时内尝试对临界资源加锁,加锁成功则返回 true ;始终加不上则返回 false
    template <class _Time>                   // try to lock the mutex with timeout
    bool _Try_lock_until( _Time  _Abs_time ) // 本函是最基本的成员函数,被别的成员函数调用
    {
        unique_lock<mutex> _Lock(_My_mutex); // 加锁成功
        
        // 条件变量 condition_variable 的限时等待的语义是:若未超时下的断言为假,
        // 则继续睡眠等待直到断言为真; 超时后的条件唤醒则直接返回断言结果,断言为假也不再睡眠。
        if (  ! _My_cond.wait_until(_Lock, _Abs_time, _UInt_is_zero{ _My_locked } )  )
            return false; 
            
        _My_locked = UINT_MAX;
        return true;
    }

    // try to lock the mutex with timeout  调用上面的更底层的函数,语义完全一样
    bool try_lock_until(const xtime* _Abs_time) { return _Try_lock_until(_Abs_time); }

    template <class _Clock, class _Duration>  // try to lock the mutex with timeout
    bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time)
    {
#if _HAS_CXX20
        static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
        return _Try_lock_until(_Abs_time);    // 调用了上面的成员函数
    }

    template <class _Rep, class _Period>   // try to lock for duration
    bool try_lock_for(const chrono::duration<_Rep, _Period>& _Rel_time) // 调用上面的成员函数
    { 
        return try_lock_until( _To_absolute_time(_Rel_time) );  
    }
    // 函 _To_absolute_time 的返回值类型是 time_point <  steady_clock , duration<long_long,nano>  >
    // auto _To_absolute_time (const chrono::duration<_Rep, _Period>& _Rel_time ) 
};

//****************************************************************************************************

// enum { _Mtx_plain=0x01 , _Mtx_try=0x02 , _Mtx_timed=0x04 , _Mtx_recursive=0x100 }; // mutex types
// class _Mutex_base { _Mutex_base(int _Flags = 0) { _Mtx_init_in_situ(_Mymtx(), _Flags | _Mtx_try); }  };
// class recursive_mutex : _Mutex_base {  recursive_mutex() : _Mutex_base(_Mtx_recursive) {} };
class recursive_timed_mutex          // class for recursive timed mutual exclusion
{ 
private:                             // _My_locked 非 0 表已有线程抢占了临界资源 ;
    unsigned int        _My_locked ; // 此值为 0 表本线程可以占有临界资源,并修改本值为 非0 。
    mutex               _My_mutex  ; // 此处的 mutex 保护的是对数据成员 _My_locked 的访问的原子性
    condition_variable  _My_cond   ; // 为了实现线程同步, mutex 与条件变量总是同时使用、同时出现。
    thread::id          _My_owner  ; // 记录本锁已被哪个线程拥有

public:
    // 默认的构造函数。没有显式定义的析构函数。_My_locked 的含义是本线程加了几次锁,故初始化为 0 。
    recursive_timed_mutex() noexcept : _My_locked(0) {} 

    recursive_timed_mutex(const recursive_timed_mutex&) = delete;  // 禁止 copy 构造函数
    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; // 禁止 copy 赋值运算符函数

    void lock()  // lock the mutex 。从本函数可以看出:递归锁,加了几次锁,也要解锁几次。!!
    { 
        const thread::id _Tid = this_thread::get_id(); // 获取运行此函数的线程的 id 

        unique_lock<mutex> _Lock(_My_mutex); // 加锁

        if (_Tid == _My_owner) // 若是已经持有锁的线程对锁的重复加锁
        {
            if (_My_locked < UINT_MAX)   // 可见,允许持有锁的线程再次加锁
                ++_My_locked;  // 更新加锁的次数
            else               // 加锁次数太多,报错。但这个数据非常大, u_int 的最大值。
                _Throw_system_error(errc::device_or_resource_busy);
        } 
        else  // 未持有锁的线程也想加锁,只能睡眠等待,这符合 锁 的语义,lock()函数的定义
        {
            while ( _My_locked != 0 )   _My_cond.wait(_Lock); // wait(..) 睡眠前,本线程会释放锁的 

            _My_locked = 1;   // 出了上面的 while 与 wait ,此时当前线程已经获得锁了
            _My_owner  = _Tid;
        }
    }

    // 可见本模板的 unlock() 函数还兼有 condition_variable.notify() 的功能
    void unlock()  // unlock the mutex 没把本线程加锁的次数解锁完,就不必唤醒别的等待锁的线程
    {
        bool _Do_notify = false;  // 只有在本线程加锁的次数,全部清零,才可以解锁,否则不解锁

        {
            lock_guard<mutex> _Lock(_My_mutex); // 缩小了锁保护的代码段

            --_My_locked;  // 加锁的次数减一

            if (_My_locked == 0) {
                _Do_notify = true;
                _My_owner = thread::id();  // 把记录线程 id 的字段清零
            }
        }

        if ( _Do_notify )  _My_cond.notify_one();   // 唤醒等待的线程
    }

    bool try_lock() noexcept  // try to lock the mutex
    { 
        const thread::id _Tid = this_thread::get_id();   // 获取运行此函数的当前线程的 id 

        lock_guard<mutex> _Lock(_My_mutex);   // 此锁在本函数退出时,解开。

        if (_Tid == _My_owner)      // 说明获得 锁 的线程,也可以多次调用 try_lock()
        {
            if (_My_locked < UINT_MAX) 
                ++_My_locked;       // 叠加加锁的次数,跟 lock(..) 的功能一样
            else 
                return false;
        }
        else 
        {
            if (_My_locked != 0) // 若别的线程得不到锁, try_lock 不会 wait 等待,直接返回 false
                return false;
            else                 // 说明锁空闲了。没有任何线程占有锁。所以本线程可以占有锁。
            {
                _My_locked = 1;
                _My_owner  = _Tid;
            }
        }
        return true;
    }

    //********************以下函数与时间有关了

    template <class _Time>  // try to lock the mutex with timeout
    bool _Try_lock_until(_Time _Abs_time) // 本函数是最基础的函数,被别的成员函数调用
    {
        const thread::id _Tid = this_thread::get_id();  // 获取运行此函数的线程的 id 

        unique_lock<mutex> _Lock(_My_mutex);

        if (_Tid == _My_owner)  // 说明本线程在获得锁以后,又请求加锁
        {
            if (_My_locked < UINT_MAX)    // 这里说明加上锁了,不用等待
                ++_My_locked;
            else
                return false;
        }
        else   // 此时可能锁空闲,成员 _My_owner = 0 ; 也可能是锁被别的线程占有
        {   // condition_variable.wait_until(..) 有两个版本,支持不同形式的时间点
            if (!_My_cond.wait_until(_Lock, _Abs_time, _UInt_is_zero{ _My_locked }))
                return false;
    // struct _UInt_is_zero { u_int& _UInt;  bool operator()() { return _UInt == 0; }  };

            _My_locked = 1;
            _My_owner = _Tid;  // 数据成员 _My_owner 更改为当前线程的 id 
        }

        return true;
    }

    // try to lock the mutex with timeout , 可见,这俩成员函数的功能完全一样,只是函数名不同
    bool try_lock_until(const xtime* _Abs_time) {  return _Try_lock_until(_Abs_time);  }

    template <class _Clock, class _Duration>   // try to lock the mutex with timeout
    bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) // 重载成员函数
    {
#if _HAS_CXX20
        static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
        return _Try_lock_until(_Abs_time);
    }

    template <class _Rep, class _Period>         // try to lock for duration
    bool try_lock_for(const chrono::duration<_Rep, _Period>& _Rel_time)
    { 
        return try_lock_until( _To_absolute_time(_Rel_time) );
    }
    // 函 _To_absolute_time 的返回值类型是 time_point <  steady_clock , duration<long_long,nano>  >
    // auto _To_absolute_time (const chrono::duration<_Rep, _Period>& _Rel_time ) 

};

//****************************************************************************************************

#if _HAS_CXX17
template <class... _Mutexes>
class _NODISCARD scoped_lock  // 这里似乎是以一个类的方式,来管理多个锁
{   // class with destructor that unlocks mutexes
private:
    tuple<_Mutexes&...> _MyMutexes;
public:
    // construct and lock
    explicit scoped_lock(_Mutexes&... _Mtxes) : _MyMutexes(_Mtxes...) {  _STD lock(_Mtxes...); }

    // construct but don't lock
    explicit scoped_lock(adopt_lock_t, _Mutexes&... _Mtxes) : _MyMutexes(_Mtxes...) {}

    ~scoped_lock() noexcept 
    {
        _STD apply([](_Mutexes&... _Mtxes) { (..., (void)_Mtxes.unlock()); }, _MyMutexes);
    }

    scoped_lock(const scoped_lock&) = delete;
    scoped_lock& operator=(const scoped_lock&) = delete;
};

template <class _Mutex>
class _NODISCARD scoped_lock<_Mutex> 
{
private:
    _Mutex& _MyMutex;
public:
    using mutex_type = _Mutex;

    // construct and lock
    explicit scoped_lock(_Mutex& _Mtx) : _MyMutex(_Mtx) { _MyMutex.lock(); }

    // construct but don't lock
    explicit scoped_lock(adopt_lock_t, _Mutex& _Mtx) : _MyMutex(_Mtx) {} 

    ~scoped_lock() noexcept {  _MyMutex.unlock(); }

    scoped_lock(const scoped_lock&) = delete;
    scoped_lock& operator=(const scoped_lock&) = delete;
};

template <>
class scoped_lock<>
{
public:
    explicit scoped_lock() {}
    explicit scoped_lock(adopt_lock_t) {}
    ~scoped_lock() noexcept {}

    scoped_lock(const scoped_lock&) = delete;
    scoped_lock& operator=(const scoped_lock&) = delete;
};
#endif // _HAS_CXX17


//***************************************************************************************************



#endif // _M_CEE


_STD_END
// #define _STD_END   } ,在 std  命名空间里的操作结束

#pragma pop_macro("new") 
// 恢复最开始隐藏的 new 宏定义,#pragma push_macro("new")

_STL_RESTORE_CLANG_WARNINGS
// 对应最开始的,此处是恢复 clang 警告

#pragma warning(pop)
// 恢复原来的警告级别  #pragma warning(push, _STL_WARNING_LEVEL)

#pragma pack(pop)
// 恢复原来的内存对齐方式  #pragma pack(push, _CRT_PACKING) 

#endif // _STL_COMPILER_PREPROCESSOR,本文件在此 #if 成立时才存在


#endif // _MUTEX_

(46)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值