mirror of
https://github.com/tearshark/librf.git
synced 2024-10-01 15:57:07 +08:00
完善mutex_t的接口
This commit is contained in:
parent
e22ae5dc12
commit
9d94bfa30c
@ -9,24 +9,24 @@ RESUMEF_NS
|
|||||||
|
|
||||||
inline namespace mutex_v2
|
inline namespace mutex_v2
|
||||||
{
|
{
|
||||||
struct [[nodiscard]] scoped_lock_mutex_t;
|
struct adopt_manual_unlock_t{};
|
||||||
struct [[nodiscard]] scoped_unlock_range_t;
|
constexpr adopt_manual_unlock_t adopt_manual_unlock;
|
||||||
|
|
||||||
|
template<class... _Mtxs>
|
||||||
|
struct [[nodiscard]] scoped_unlock_t;
|
||||||
|
|
||||||
//支持递归的锁
|
//支持递归的锁
|
||||||
struct mutex_t
|
struct mutex_t
|
||||||
{
|
{
|
||||||
typedef std::shared_ptr<detail::mutex_v2_impl> mutex_impl_ptr;
|
bool is_locked() const;
|
||||||
typedef std::chrono::system_clock clock_type;
|
|
||||||
|
|
||||||
mutex_t();
|
|
||||||
mutex_t(std::adopt_lock_t) noexcept;
|
|
||||||
~mutex_t() noexcept;
|
|
||||||
|
|
||||||
struct lock_awaiter;
|
struct lock_awaiter;
|
||||||
struct [[nodiscard]] awaiter;
|
struct [[nodiscard]] awaiter;
|
||||||
|
struct [[nodiscard]] manual_awaiter;
|
||||||
|
|
||||||
awaiter/*scoped_lock_mutex_t*/ lock() const noexcept;
|
awaiter/*scoped_unlock_t*/ lock() const noexcept;
|
||||||
awaiter/*scoped_lock_mutex_t*/ operator co_await() const noexcept;
|
awaiter/*scoped_unlock_t*/ operator co_await() const noexcept;
|
||||||
|
manual_awaiter/*void*/ lock(adopt_manual_unlock_t) const noexcept;
|
||||||
|
|
||||||
struct [[nodiscard]] try_awaiter;
|
struct [[nodiscard]] try_awaiter;
|
||||||
//co_await try_lock()获得是否加锁成功。此操作无论成功与否都会立即返回。
|
//co_await try_lock()获得是否加锁成功。此操作无论成功与否都会立即返回。
|
||||||
@ -55,34 +55,38 @@ RESUMEF_NS
|
|||||||
void unlock(void* unique_address) const;
|
void unlock(void* unique_address) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct _MutexAwaitAssembleT;
|
|
||||||
|
|
||||||
template<class... _Mtxs
|
template<class... _Mtxs
|
||||||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<std::remove_cvref_t<_Mtxs>, mutex_t>...>>
|
, typename = std::enable_if_t<std::conjunction_v<std::is_same<std::remove_cvref_t<_Mtxs>, mutex_t>...>>
|
||||||
>
|
>
|
||||||
static future_t<scoped_unlock_range_t> lock(_Mtxs&... mtxs);
|
static future_t<scoped_unlock_t<_Mtxs...>> lock(_Mtxs&... mtxs);
|
||||||
|
|
||||||
|
|
||||||
template<class... _Mtxs
|
template<class... _Mtxs
|
||||||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<std::remove_cvref_t<_Mtxs>, mutex_t>...>>
|
, typename = std::enable_if_t<std::conjunction_v<std::is_same<std::remove_cvref_t<_Mtxs>, mutex_t>...>>
|
||||||
>
|
>
|
||||||
static scoped_unlock_range_t lock(void* unique_address, _Mtxs&... mtxs);
|
static scoped_unlock_t<_Mtxs...> lock(void* unique_address, _Mtxs&... mtxs);
|
||||||
|
|
||||||
template<class... _Mtxs
|
template<class... _Mtxs
|
||||||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<std::remove_cvref_t<_Mtxs>, mutex_t>...>>
|
, typename = std::enable_if_t<std::conjunction_v<std::is_same<std::remove_cvref_t<_Mtxs>, mutex_t>...>>
|
||||||
>
|
>
|
||||||
static void unlock(void* unique_address, _Mtxs&... mtxs);
|
static void unlock(void* unique_address, _Mtxs&... mtxs);
|
||||||
|
|
||||||
bool is_locked() const;
|
mutex_t();
|
||||||
auto lock(std::defer_lock_t) const noexcept;
|
mutex_t(std::adopt_lock_t) noexcept;
|
||||||
|
~mutex_t() noexcept;
|
||||||
|
|
||||||
mutex_t(const mutex_t&) = default;
|
mutex_t(const mutex_t&) = default;
|
||||||
mutex_t(mutex_t&&) = default;
|
mutex_t(mutex_t&&) = default;
|
||||||
mutex_t& operator = (const mutex_t&) = default;
|
mutex_t& operator = (const mutex_t&) = default;
|
||||||
mutex_t& operator = (mutex_t&&) = default;
|
mutex_t& operator = (mutex_t&&) = default;
|
||||||
|
|
||||||
|
typedef std::shared_ptr<detail::mutex_v2_impl> mutex_impl_ptr;
|
||||||
|
typedef std::chrono::system_clock clock_type;
|
||||||
private:
|
private:
|
||||||
friend struct scoped_lock_mutex_t;
|
struct _MutexAwaitAssembleT;
|
||||||
|
|
||||||
|
template<class... _Mtxs> friend struct scoped_unlock_t;
|
||||||
|
|
||||||
mutex_impl_ptr _mutex;
|
mutex_impl_ptr _mutex;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -166,21 +166,22 @@ RESUMEF_NS
|
|||||||
|
|
||||||
inline namespace mutex_v2
|
inline namespace mutex_v2
|
||||||
{
|
{
|
||||||
struct [[nodiscard]] scoped_lock_mutex_t
|
template<>
|
||||||
|
struct [[nodiscard]] scoped_unlock_t<mutex_t>
|
||||||
{
|
{
|
||||||
typedef std::shared_ptr<detail::mutex_v2_impl> mutex_impl_ptr;
|
typedef std::shared_ptr<detail::mutex_v2_impl> mutex_impl_ptr;
|
||||||
|
|
||||||
scoped_lock_mutex_t() {}
|
scoped_unlock_t() {}
|
||||||
|
|
||||||
//此函数,应该在try_lock()获得锁后使用
|
//此函数,应该在try_lock()获得锁后使用
|
||||||
//或者在协程里,由awaiter使用
|
//或者在协程里,由awaiter使用
|
||||||
scoped_lock_mutex_t(std::adopt_lock_t, mutex_impl_ptr mtx, void* sch)
|
scoped_unlock_t(std::adopt_lock_t, void* sch, mutex_impl_ptr mtx)
|
||||||
: _mutex(std::move(mtx))
|
: _mutex(std::move(mtx))
|
||||||
, _owner(sch)
|
, _owner(sch)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//此函数,适合在非协程里使用
|
//此函数,适合在非协程里使用
|
||||||
scoped_lock_mutex_t(mutex_impl_ptr mtx, void* sch)
|
scoped_unlock_t(void* sch, mutex_impl_ptr mtx)
|
||||||
: _mutex(std::move(mtx))
|
: _mutex(std::move(mtx))
|
||||||
, _owner(sch)
|
, _owner(sch)
|
||||||
{
|
{
|
||||||
@ -189,14 +190,14 @@ RESUMEF_NS
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
scoped_lock_mutex_t(std::adopt_lock_t, const mutex_t& mtx, void* sch)
|
scoped_unlock_t(std::adopt_lock_t, void* sch, const mutex_t& mtx)
|
||||||
: scoped_lock_mutex_t(std::adopt_lock, mtx._mutex, sch)
|
: scoped_unlock_t(std::adopt_lock, sch, mtx._mutex)
|
||||||
{}
|
{}
|
||||||
scoped_lock_mutex_t(const mutex_t& mtx, void* sch)
|
scoped_unlock_t(void* sch, const mutex_t& mtx)
|
||||||
: scoped_lock_mutex_t(mtx._mutex, sch)
|
: scoped_unlock_t(sch, mtx._mutex)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~scoped_lock_mutex_t()
|
~scoped_unlock_t()
|
||||||
{
|
{
|
||||||
if (_mutex != nullptr)
|
if (_mutex != nullptr)
|
||||||
_mutex->unlock(_owner);
|
_mutex->unlock(_owner);
|
||||||
@ -211,31 +212,10 @@ RESUMEF_NS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_locked() const noexcept
|
scoped_unlock_t(const scoped_unlock_t&) = delete;
|
||||||
{
|
scoped_unlock_t& operator = (const scoped_unlock_t&) = delete;
|
||||||
return _mutex != nullptr && _mutex->owner() == _owner;
|
scoped_unlock_t(scoped_unlock_t&& _Right) = default;
|
||||||
}
|
scoped_unlock_t& operator = (scoped_unlock_t&& _Right) = default;
|
||||||
|
|
||||||
scoped_lock_mutex_t(const scoped_lock_mutex_t&) = delete;
|
|
||||||
scoped_lock_mutex_t& operator = (const scoped_lock_mutex_t&) = delete;
|
|
||||||
|
|
||||||
scoped_lock_mutex_t(scoped_lock_mutex_t&& _Right) noexcept
|
|
||||||
: _mutex(std::move(_Right._mutex))
|
|
||||||
, _owner(_Right._owner)
|
|
||||||
{
|
|
||||||
assert(_Right._mutex == nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
scoped_lock_mutex_t& operator = (scoped_lock_mutex_t&& _Right) noexcept
|
|
||||||
{
|
|
||||||
if (this != &_Right)
|
|
||||||
{
|
|
||||||
_mutex = std::move(_Right._mutex);
|
|
||||||
assert(_Right._mutex == nullptr);
|
|
||||||
_owner = _Right._owner;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
mutex_impl_ptr _mutex;
|
mutex_impl_ptr _mutex;
|
||||||
void* _owner;
|
void* _owner;
|
||||||
@ -293,12 +273,12 @@ RESUMEF_NS
|
|||||||
{
|
{
|
||||||
using lock_awaiter::lock_awaiter;
|
using lock_awaiter::lock_awaiter;
|
||||||
|
|
||||||
scoped_lock_mutex_t await_resume() noexcept
|
scoped_unlock_t<mutex_t> await_resume() noexcept
|
||||||
{
|
{
|
||||||
mutex_impl_ptr mtx = _mutex ? _mutex->shared_from_this() : nullptr;
|
mutex_impl_ptr mtx = _mutex ? _mutex->shared_from_this() : nullptr;
|
||||||
_mutex = nullptr;
|
_mutex = nullptr;
|
||||||
|
|
||||||
return { std::adopt_lock, mtx, _root };
|
return { std::adopt_lock, _root, mtx };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -312,18 +292,18 @@ RESUMEF_NS
|
|||||||
return { _mutex.get() };
|
return { _mutex.get() };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto mutex_t::lock(std::defer_lock_t) const noexcept
|
struct mutex_t::manual_awaiter : public lock_awaiter
|
||||||
{
|
{
|
||||||
struct discard_unlock_awaiter : lock_awaiter
|
using lock_awaiter::lock_awaiter;
|
||||||
|
void await_resume() noexcept
|
||||||
{
|
{
|
||||||
using lock_awaiter::lock_awaiter;
|
_mutex = nullptr;
|
||||||
void await_resume() noexcept
|
}
|
||||||
{
|
};
|
||||||
_mutex = nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return discard_unlock_awaiter{ _mutex.get() };
|
inline mutex_t::manual_awaiter mutex_t::lock(adopt_manual_unlock_t) const noexcept
|
||||||
|
{
|
||||||
|
return { _mutex.get() };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool mutex_t::is_locked() const
|
inline bool mutex_t::is_locked() const
|
||||||
@ -485,6 +465,8 @@ RESUMEF_NS
|
|||||||
_mutex->unlock(unique_address);
|
_mutex->unlock(unique_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct mutex_t::_MutexAwaitAssembleT
|
struct mutex_t::_MutexAwaitAssembleT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -506,7 +488,7 @@ RESUMEF_NS
|
|||||||
}
|
}
|
||||||
auto _Lock_ref(mutex_t& _LkN) const
|
auto _Lock_ref(mutex_t& _LkN) const
|
||||||
{
|
{
|
||||||
return _LkN.lock(std::defer_lock);
|
return _LkN.lock(adopt_manual_unlock);
|
||||||
}
|
}
|
||||||
auto _Try_lock_ref(mutex_t& _LkN) const
|
auto _Try_lock_ref(mutex_t& _LkN) const
|
||||||
{
|
{
|
||||||
@ -527,24 +509,36 @@ RESUMEF_NS
|
|||||||
future_t<> _ReturnValue() const;
|
future_t<> _ReturnValue() const;
|
||||||
template<class U>
|
template<class U>
|
||||||
future_t<U> _ReturnValue(U v) const;
|
future_t<U> _ReturnValue(U v) const;
|
||||||
|
|
||||||
|
_MutexAwaitAssembleT(const _MutexAwaitAssembleT&) = default;
|
||||||
|
_MutexAwaitAssembleT& operator = (const _MutexAwaitAssembleT&) = default;
|
||||||
|
_MutexAwaitAssembleT(_MutexAwaitAssembleT&& _Right) = default;
|
||||||
|
_MutexAwaitAssembleT& operator = (_MutexAwaitAssembleT&& _Right) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct [[nodiscard]] scoped_unlock_range_t
|
template<class... _Mtxs>
|
||||||
|
struct [[nodiscard]] scoped_unlock_t
|
||||||
{
|
{
|
||||||
mutex_t::_MutexAwaitAssembleT _MAA;
|
mutex_t::_MutexAwaitAssembleT _MAA;
|
||||||
|
|
||||||
//此函数,应该在try_lock()获得锁后使用
|
//此函数,应该在try_lock()获得锁后使用
|
||||||
//或者在协程里,由awaiter使用
|
//或者在协程里,由awaiter使用
|
||||||
template<class... _Mtxs>
|
template<class... U>
|
||||||
scoped_unlock_range_t(void* unique_address, _Mtxs&&... mtxs)
|
scoped_unlock_t(void* sch, U&&... mtxs)
|
||||||
: _MAA(unique_address, std::forward<_Mtxs>(mtxs)...)
|
: _MAA(sch, std::forward<U>(mtxs)...)
|
||||||
|
{
|
||||||
|
detail::scoped_lock_range_lock_impl::_Lock_range(_MAA);
|
||||||
|
}
|
||||||
|
template<class... U>
|
||||||
|
scoped_unlock_t(std::adopt_lock_t, void* sch, U&&... mtxs)
|
||||||
|
: _MAA(sch, std::forward<U>(mtxs)...)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~scoped_unlock_range_t()
|
~scoped_unlock_t()
|
||||||
{
|
{
|
||||||
if (_MAA._owner != nullptr)
|
if (_MAA._owner != nullptr)
|
||||||
{
|
{
|
||||||
for(mutex_t& mtx : _MAA._mutex)
|
for (mutex_t& mtx : _MAA._mutex)
|
||||||
mtx.unlock(_MAA._owner);
|
mtx.unlock(_MAA._owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,29 +553,28 @@ RESUMEF_NS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_unlock_range_t(const scoped_unlock_range_t&) = delete;
|
scoped_unlock_t(const scoped_unlock_t&) = delete;
|
||||||
scoped_unlock_range_t& operator = (const scoped_unlock_range_t&) = delete;
|
scoped_unlock_t& operator = (const scoped_unlock_t&) = delete;
|
||||||
scoped_unlock_range_t(scoped_unlock_range_t&& _Right) noexcept = default;
|
scoped_unlock_t(scoped_unlock_t&& _Right) = default;
|
||||||
scoped_unlock_range_t& operator = (scoped_unlock_range_t&& _Right) noexcept = default;
|
scoped_unlock_t& operator = (scoped_unlock_t&& _Right) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class... _Mtxs>
|
||||||
|
scoped_unlock_t()->scoped_unlock_t<scoped_unlock_t<_Mtxs...>&&>;
|
||||||
|
|
||||||
template<class... _Mtxs, typename>
|
template<class... _Mtxs, typename>
|
||||||
inline future_t<scoped_unlock_range_t> mutex_t::lock(_Mtxs&... mtxs)
|
inline future_t<scoped_unlock_t<_Mtxs...>> mutex_t::lock(_Mtxs&... mtxs)
|
||||||
{
|
{
|
||||||
scoped_unlock_range_t unlock_guard{ root_state(), mtxs... };
|
scoped_unlock_t<_Mtxs...> unlock_guard{ std::adopt_lock, root_state(), mtxs... };
|
||||||
co_await detail::mutex_lock_await_lock_impl::_Lock_range(unlock_guard._MAA);
|
co_await detail::mutex_lock_await_lock_impl::_Lock_range(unlock_guard._MAA);
|
||||||
co_return unlock_guard;
|
co_return std::move(unlock_guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class... _Mtxs, typename>
|
template<class... _Mtxs, typename>
|
||||||
inline scoped_unlock_range_t mutex_t::lock(void* unique_address, _Mtxs&... mtxs)
|
inline scoped_unlock_t<_Mtxs...> mutex_t::lock(void* unique_address, _Mtxs&... mtxs)
|
||||||
{
|
{
|
||||||
assert(unique_address != nullptr);
|
assert(unique_address != nullptr);
|
||||||
|
return { unique_address, mtxs... };
|
||||||
detail::_MutexAddressAssembleT MAA(unique_address, mtxs...);
|
|
||||||
detail::scoped_lock_range_lock_impl::_Lock_range(MAA);
|
|
||||||
|
|
||||||
return scoped_unlock_range_t{ std::move(MAA._Lks), unique_address };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class... _Mtxs, typename>
|
template<class... _Mtxs, typename>
|
||||||
|
@ -23,14 +23,14 @@ static future_t<> test_mutex_pop(size_t idx)
|
|||||||
for (size_t i = 0; i < N / 2; ++i)
|
for (size_t i = 0; i < N / 2; ++i)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
auto _locker = co_await g_lock.lock(); //_locker析构后,会调用对应的unlock()函数。
|
scoped_unlock_t _locker = co_await g_lock.lock(); //_locker析构后,会调用对应的unlock()函数。
|
||||||
|
|
||||||
--g_counter;
|
--g_counter;
|
||||||
std::cout << "pop :" << g_counter << " on " << idx << std::endl;
|
std::cout << "pop :" << g_counter << " on " << idx << std::endl;
|
||||||
|
|
||||||
co_await 50ms;
|
co_await 50ms;
|
||||||
|
|
||||||
auto _locker_2 = co_await g_lock;
|
scoped_unlock_t _locker_2 = co_await g_lock;
|
||||||
|
|
||||||
--g_counter;
|
--g_counter;
|
||||||
std::cout << "pop :" << g_counter << " on " << idx << std::endl;
|
std::cout << "pop :" << g_counter << " on " << idx << std::endl;
|
||||||
@ -47,7 +47,7 @@ static future_t<> test_mutex_push(size_t idx)
|
|||||||
for (size_t i = 0; i < N; ++i)
|
for (size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
auto _locker = co_await g_lock.lock();
|
scoped_unlock_t _locker = co_await g_lock.lock();
|
||||||
|
|
||||||
++g_counter;
|
++g_counter;
|
||||||
std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
||||||
@ -105,7 +105,7 @@ static std::thread test_mutex_async_push(size_t idx)
|
|||||||
{
|
{
|
||||||
if (g_lock.try_lock_for(500ms, &provide_unique_address))
|
if (g_lock.try_lock_for(500ms, &provide_unique_address))
|
||||||
{
|
{
|
||||||
//scoped_lock_mutex_t _locker(std::adopt_lock, g_lock, &provide_unique_address);
|
//scoped_unlock_t _locker(std::adopt_lock, g_lock, &provide_unique_address);
|
||||||
|
|
||||||
++g_counter;
|
++g_counter;
|
||||||
std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
||||||
@ -143,9 +143,9 @@ static void resumable_mutex_async()
|
|||||||
|
|
||||||
static future_t<> resumable_mutex_range_push(size_t idx, mutex_t a, mutex_t b, mutex_t c)
|
static future_t<> resumable_mutex_range_push(size_t idx, mutex_t a, mutex_t b, mutex_t c)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 1000001; ++i)
|
for (int i = 0; i < 1000; ++i)
|
||||||
{
|
{
|
||||||
auto __lockers = co_await mutex_t::lock(a, b, c);
|
scoped_unlock_t __lockers = co_await mutex_t::lock(a, b, c);
|
||||||
assert(a.is_locked());
|
assert(a.is_locked());
|
||||||
assert(b.is_locked());
|
assert(b.is_locked());
|
||||||
assert(c.is_locked());
|
assert(c.is_locked());
|
||||||
@ -159,9 +159,9 @@ static future_t<> resumable_mutex_range_push(size_t idx, mutex_t a, mutex_t b, m
|
|||||||
|
|
||||||
static future_t<> resumable_mutex_range_pop(size_t idx, mutex_t a, mutex_t b, mutex_t c)
|
static future_t<> resumable_mutex_range_pop(size_t idx, mutex_t a, mutex_t b, mutex_t c)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 1000000; ++i)
|
for (int i = 0; i < 1000; ++i)
|
||||||
{
|
{
|
||||||
auto __lockers = co_await mutex_t::lock(a, b, c);
|
scoped_unlock_t __lockers = co_await mutex_t::lock(a, b, c);
|
||||||
assert(a.is_locked());
|
assert(a.is_locked());
|
||||||
assert(b.is_locked());
|
assert(b.is_locked());
|
||||||
assert(c.is_locked());
|
assert(c.is_locked());
|
||||||
@ -199,11 +199,11 @@ static void resumable_mutex_lock_range()
|
|||||||
|
|
||||||
void resumable_main_mutex()
|
void resumable_main_mutex()
|
||||||
{
|
{
|
||||||
//resumable_mutex_synch();
|
resumable_mutex_synch();
|
||||||
//std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
//resumable_mutex_async();
|
resumable_mutex_async();
|
||||||
//std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
resumable_mutex_lock_range();
|
resumable_mutex_lock_range();
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,13 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>ClangCL</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>ClangCL</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>NotSet</CharacterSet>
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
Loading…
Reference in New Issue
Block a user