1
0
mirror of https://github.com/tearshark/librf.git synced 2024-10-01 15:57:07 +08:00

实现mutex第二版

This commit is contained in:
tearshark 2020-03-18 18:36:39 +08:00
parent ca0177e3bb
commit 946656e34e
16 changed files with 649 additions and 227 deletions

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#define LIB_RESUMEF_VERSION 20700 // 2.7.0 #define LIB_RESUMEF_VERSION 20800 // 2.8.0
#if defined(RESUMEF_MODULE_EXPORT) #if defined(RESUMEF_MODULE_EXPORT)
#define RESUMEF_NS export namespace resumef #define RESUMEF_NS export namespace resumef

View File

@ -10,6 +10,7 @@ RESUMEF_NS
unlock_more, // unlock 次数多余lock次数 unlock_more, // unlock 次数多余lock次数
read_before_write, // 0容量的channel先读后写 read_before_write, // 0容量的channel先读后写
timer_canceled, // 定时器被意外取消 timer_canceled, // 定时器被意外取消
not_await_lock, // 没有在协程中使用co_await等待lock结果
max__ max__
}; };

View File

@ -1,89 +1,5 @@
#pragma once #pragma once
RESUMEF_NS #include "mutex_v1.h"
{ #include "mutex_v2.h"
namespace detail #include "mutex_v2.inl"
{
struct mutex_impl;
typedef ::resumef::detail::_awaker<mutex_impl> mutex_awaker;
typedef std::shared_ptr<mutex_awaker> mutex_awaker_ptr;
struct mutex_impl : public std::enable_shared_from_this<mutex_impl>
{
private:
//typedef spinlock lock_type;
typedef std::recursive_mutex lock_type;
std::list<mutex_awaker_ptr> _awakes;
mutex_awaker_ptr _owner;
lock_type _lock;
public:
mutex_impl();
//如果已经触发了awaker,则返回true
bool lock_(const mutex_awaker_ptr& awaker);
bool try_lock_(const mutex_awaker_ptr& awaker);
void unlock();
template<class callee_t, class dummy_t = std::enable_if<!std::is_same<std::remove_cv_t<callee_t>, mutex_awaker_ptr>::value>>
decltype(auto) lock(callee_t&& awaker, dummy_t* dummy_ = nullptr)
{
(void)dummy_;
return lock_(std::make_shared<mutex_awaker>(std::forward<callee_t>(awaker)));
}
private:
mutex_impl(const mutex_impl&) = delete;
mutex_impl(mutex_impl&&) = delete;
mutex_impl& operator = (const mutex_impl&) = delete;
mutex_impl& operator = (mutex_impl&&) = delete;
};
}
struct mutex_t
{
typedef std::shared_ptr<detail::mutex_impl> lock_impl_ptr;
typedef std::weak_ptr<detail::mutex_impl> lock_impl_wptr;
typedef std::chrono::system_clock clock_type;
private:
lock_impl_ptr _locker;
public:
mutex_t();
void unlock() const
{
_locker->unlock();
}
future_t<bool> lock() const;
bool try_lock() const;
/*
template<class _Rep, class _Period>
awaitable_t<bool>
try_lock_for(const std::chrono::duration<_Rep, _Period> & dt) const
{
return try_lock_for_(std::chrono::duration_cast<clock_type::duration>(dt));
}
template<class _Clock, class _Duration>
awaitable_t<bool>
try_lock_until(const std::chrono::time_point<_Clock, _Duration> & tp) const
{
return try_lock_until_(std::chrono::time_point_cast<clock_type::duration>(tp));
}
*/
mutex_t(const mutex_t&) = default;
mutex_t(mutex_t&&) = default;
mutex_t& operator = (const mutex_t&) = default;
mutex_t& operator = (mutex_t&&) = default;
private:
inline future_t<bool> try_lock_for_(const clock_type::duration& dt) const
{
return try_lock_until_(clock_type::now() + dt);
}
future_t<bool> try_lock_until_(const clock_type::time_point& tp) const;
};
}

View File

@ -33,7 +33,7 @@ RESUMEF_NS
} }
} }
bool mutex_impl::lock_(const mutex_awaker_ptr & awaker) bool mutex_impl::lock_(const mutex_awaker_ptr& awaker)
{ {
assert(awaker); assert(awaker);
@ -52,7 +52,7 @@ RESUMEF_NS
} }
} }
bool mutex_impl::try_lock_(const mutex_awaker_ptr & awaker) bool mutex_impl::try_lock_(const mutex_awaker_ptr& awaker)
{ {
assert(awaker); assert(awaker);
@ -71,6 +71,9 @@ RESUMEF_NS
} }
namespace mutex_v1
{
mutex_t::mutex_t() mutex_t::mutex_t()
: _locker(std::make_shared<detail::mutex_impl>()) : _locker(std::make_shared<detail::mutex_impl>())
{ {
@ -81,7 +84,7 @@ RESUMEF_NS
awaitable_t<bool> awaitable; awaitable_t<bool> awaitable;
auto awaker = std::make_shared<detail::mutex_awaker>( auto awaker = std::make_shared<detail::mutex_awaker>(
[st = awaitable._state](detail::mutex_impl * e) -> bool [st = awaitable._state](detail::mutex_impl* e) -> bool
{ {
st->set_value(e ? true : false); st->set_value(e ? true : false);
return true; return true;
@ -94,19 +97,19 @@ RESUMEF_NS
bool mutex_t::try_lock() const bool mutex_t::try_lock() const
{ {
auto dummy_awaker = std::make_shared<detail::mutex_awaker>( auto dummy_awaker = std::make_shared<detail::mutex_awaker>(
[](detail::mutex_impl * ) -> bool [](detail::mutex_impl*) -> bool
{ {
return true; return true;
}); });
return _locker->try_lock_(dummy_awaker); return _locker->try_lock_(dummy_awaker);
} }
future_t<bool> mutex_t::try_lock_until_(const clock_type::time_point & tp) const future_t<bool> mutex_t::try_lock_until_(const clock_type::time_point& tp) const
{ {
awaitable_t<bool> awaitable; awaitable_t<bool> awaitable;
auto awaker = std::make_shared<detail::mutex_awaker>( auto awaker = std::make_shared<detail::mutex_awaker>(
[st = awaitable._state](detail::mutex_impl * e) -> bool [st = awaitable._state](detail::mutex_impl* e) -> bool
{ {
st->set_value(e ? true : false); st->set_value(e ? true : false);
return true; return true;
@ -114,7 +117,7 @@ RESUMEF_NS
_locker->lock_(awaker); _locker->lock_(awaker);
(void)this_scheduler()->timer()->add(tp, (void)this_scheduler()->timer()->add(tp,
[awaker](bool ) [awaker](bool)
{ {
awaker->awake(nullptr, 1); awaker->awake(nullptr, 1);
}); });
@ -122,3 +125,4 @@ RESUMEF_NS
return awaitable.get_future(); return awaitable.get_future();
} }
} }
}

92
librf/src/mutex_v1.h Normal file
View File

@ -0,0 +1,92 @@
#pragma once
RESUMEF_NS
{
namespace detail
{
struct mutex_impl;
typedef ::resumef::detail::_awaker<mutex_impl> mutex_awaker;
typedef std::shared_ptr<mutex_awaker> mutex_awaker_ptr;
struct mutex_impl : public std::enable_shared_from_this<mutex_impl>
{
private:
//typedef spinlock lock_type;
typedef std::recursive_mutex lock_type;
std::list<mutex_awaker_ptr> _awakes;
mutex_awaker_ptr _owner;
lock_type _lock;
public:
mutex_impl();
//如果已经触发了awaker,则返回true
bool lock_(const mutex_awaker_ptr& awaker);
bool try_lock_(const mutex_awaker_ptr& awaker);
void unlock();
template<class callee_t, class dummy_t = std::enable_if<!std::is_same<std::remove_cv_t<callee_t>, mutex_awaker_ptr>::value>>
decltype(auto) lock(callee_t&& awaker, dummy_t* dummy_ = nullptr)
{
(void)dummy_;
return lock_(std::make_shared<mutex_awaker>(std::forward<callee_t>(awaker)));
}
private:
mutex_impl(const mutex_impl&) = delete;
mutex_impl(mutex_impl&&) = delete;
mutex_impl& operator = (const mutex_impl&) = delete;
mutex_impl& operator = (mutex_impl&&) = delete;
};
}
namespace mutex_v1
{
struct mutex_t
{
typedef std::shared_ptr<detail::mutex_impl> lock_impl_ptr;
typedef std::weak_ptr<detail::mutex_impl> lock_impl_wptr;
typedef std::chrono::system_clock clock_type;
private:
lock_impl_ptr _locker;
public:
mutex_t();
void unlock() const
{
_locker->unlock();
}
future_t<bool> lock() const;
bool try_lock() const;
/*
template<class _Rep, class _Period>
awaitable_t<bool>
try_lock_for(const std::chrono::duration<_Rep, _Period> & dt) const
{
return try_lock_for_(std::chrono::duration_cast<clock_type::duration>(dt));
}
template<class _Clock, class _Duration>
awaitable_t<bool>
try_lock_until(const std::chrono::time_point<_Clock, _Duration> & tp) const
{
return try_lock_until_(std::chrono::time_point_cast<clock_type::duration>(tp));
}
*/
mutex_t(const mutex_t&) = default;
mutex_t(mutex_t&&) = default;
mutex_t& operator = (const mutex_t&) = default;
mutex_t& operator = (mutex_t&&) = default;
private:
inline future_t<bool> try_lock_for_(const clock_type::duration& dt) const
{
return try_lock_until_(clock_type::now() + dt);
}
future_t<bool> try_lock_until_(const clock_type::time_point& tp) const;
};
}
}

127
librf/src/mutex_v2.cpp Normal file
View File

@ -0,0 +1,127 @@
#include "../librf.h"
RESUMEF_NS
{
namespace detail
{
void state_mutex_t::resume()
{
coroutine_handle<> handler = _coro;
if (handler)
{
_coro = nullptr;
_scheduler->del_final(this);
handler.resume();
}
}
bool state_mutex_t::has_handler() const noexcept
{
return (bool)_coro;
}
state_base_t* state_mutex_t::get_parent() const noexcept
{
return _root;
}
bool state_mutex_t::on_notify()
{
assert(this->_scheduler != nullptr);
if (this->_coro)
{
this->_scheduler->add_generator(this);
return true;
}
return false;
}
void mutex_v2_impl::lock_until_succeed(void* sch)
{
assert(sch != nullptr);
for (;;)
{
if (try_lock(sch))
break;
std::this_thread::yield();
}
}
bool mutex_v2_impl::try_lock(void* sch) noexcept
{
scoped_lock<detail::mutex_v2_impl::lock_type> lock_(_lock);
return try_lock_lockless(sch);
}
bool mutex_v2_impl::try_lock_lockless(void* sch) noexcept
{
void* oldValue = _owner.load(std::memory_order_relaxed);
if (oldValue == nullptr || oldValue == sch)
{
_owner.store(sch, std::memory_order_relaxed);
_counter.fetch_add(1, std::memory_order_relaxed);
return true;
}
return false;
}
bool mutex_v2_impl::unlock(void* sch)
{
scoped_lock<lock_type> lock_(_lock);
void* oldValue = _owner.load(std::memory_order_relaxed);
if (oldValue == sch)
{
if (_counter.fetch_sub(1, std::memory_order_relaxed) == 1)
{
if (!_wait_awakes.empty())
{
state_mutex_ptr state = _wait_awakes.front();
_wait_awakes.pop_front();
//锁定状态转移到新的state上
_owner.store(state->get_root(), std::memory_order_relaxed);
_counter.fetch_add(1, std::memory_order_relaxed);
state->on_notify();
}
else
{
_owner.store(nullptr, std::memory_order_relaxed);
}
}
return true;
}
return false;
}
void mutex_v2_impl::add_wait_list_lockless(state_mutex_t* state)
{
assert(state != nullptr);
_wait_awakes.push_back(state);
}
}
inline namespace mutex_v2
{
mutex_t::mutex_t()
: _mutex(std::make_shared<detail::mutex_v2_impl>())
{
}
mutex_t::mutex_t(std::adopt_lock_t) noexcept
{
}
mutex_t::~mutex_t() noexcept
{
}
}
}

40
librf/src/mutex_v2.h Normal file
View File

@ -0,0 +1,40 @@
#pragma once
RESUMEF_NS
{
namespace detail
{
struct mutex_v2_impl;
}
inline namespace mutex_v2
{
struct scoped_lock_mutex_t;
struct mutex_t
{
typedef std::shared_ptr<detail::mutex_v2_impl> mutex_impl_ptr;
typedef std::chrono::system_clock clock_type;
mutex_t();
mutex_t(std::adopt_lock_t) noexcept;
~mutex_t() noexcept;
struct [[nodiscard]] awaiter;
awaiter lock() const noexcept;
scoped_lock_mutex_t lock(scheduler_t* sch) const noexcept;
bool try_lock(scheduler_t* sch) const noexcept;
void unlock(scheduler_t* sch) const noexcept;
mutex_t(const mutex_t&) = default;
mutex_t(mutex_t&&) = default;
mutex_t& operator = (const mutex_t&) = default;
mutex_t& operator = (mutex_t&&) = default;
private:
friend struct scoped_lock_mutex_t;
mutex_impl_ptr _mutex;
};
}
}

203
librf/src/mutex_v2.inl Normal file
View File

@ -0,0 +1,203 @@
#pragma once
RESUMEF_NS
{
namespace detail
{
struct state_mutex_t : public state_base_t
{
virtual void resume() override;
virtual bool has_handler() const noexcept override;
virtual state_base_t* get_parent() const noexcept override;
bool on_notify();
inline scheduler_t* get_scheduler() const noexcept
{
return _scheduler;
}
inline void on_await_suspend(coroutine_handle<> handler, scheduler_t* sch, state_base_t* root) noexcept
{
this->_scheduler = sch;
this->_coro = handler;
this->_root = root;
}
private:
state_base_t* _root;
//friend mutex_v2::mutex_t;
};
//做成递归锁?
struct mutex_v2_impl : public std::enable_shared_from_this<mutex_v2_impl>
{
mutex_v2_impl() {}
inline void* owner() const noexcept
{
return _owner.load(std::memory_order_relaxed);
}
bool try_lock(void* sch) noexcept; //内部加锁
bool unlock(void* sch); //内部加锁
void lock_until_succeed(void* sch); //内部加锁
public:
static constexpr bool USE_SPINLOCK = true;
using lock_type = std::conditional_t<USE_SPINLOCK, spinlock, std::recursive_mutex>;
using state_mutex_ptr = counted_ptr<state_mutex_t>;
using wait_queue_type = std::list<state_mutex_ptr>;
bool try_lock_lockless(void* sch) noexcept; //内部不加锁,加锁由外部来进行
void add_wait_list_lockless(state_mutex_t* state); //内部不加锁,加锁由外部来进行
lock_type _lock; //保证访问本对象是线程安全的
private:
std::atomic<void*> _owner = nullptr; //锁标记
std::atomic<intptr_t> _counter = 0; //递归锁的次数
wait_queue_type _wait_awakes; //等待队列
// No copying/moving
mutex_v2_impl(const mutex_v2_impl&) = delete;
mutex_v2_impl(mutex_v2_impl&&) = delete;
mutex_v2_impl& operator=(const mutex_v2_impl&) = delete;
mutex_v2_impl& operator=(mutex_v2_impl&&) = delete;
};
}
inline namespace mutex_v2
{
struct scoped_lock_mutex_t
{
typedef std::shared_ptr<detail::mutex_v2_impl> mutex_impl_ptr;
//此函数应该在try_lock()获得锁后使用
//或者在协程里由awaiter使用
scoped_lock_mutex_t(std::adopt_lock_t, detail::mutex_v2_impl* mtx, void* sch)
: _mutex(mtx->shared_from_this())
, _owner(sch)
{}
//此函数,适合在非协程里使用
scoped_lock_mutex_t(detail::mutex_v2_impl* mtx, void* sch)
: _mutex(mtx->shared_from_this())
, _owner(sch)
{
if (sch != nullptr)
_mutex->lock_until_succeed(sch);
}
scoped_lock_mutex_t(std::adopt_lock_t, const mutex_t& mtx, void* sch)
: scoped_lock_mutex_t(std::adopt_lock, mtx._mutex.get(), sch)
{}
scoped_lock_mutex_t(const mutex_t& mtx, void* sch)
: scoped_lock_mutex_t(mtx._mutex.get(), sch)
{}
~scoped_lock_mutex_t()
{
if (_mutex != nullptr)
_mutex->unlock(_owner);
}
inline void unlock() noexcept
{
if (_mutex != nullptr)
{
_mutex->unlock(_owner);
_mutex = nullptr;
}
}
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&&) = default;
scoped_lock_mutex_t& operator = (scoped_lock_mutex_t&&) = default;
private:
mutex_impl_ptr _mutex;
void* _owner;
};
struct [[nodiscard]] mutex_t::awaiter
{
awaiter(detail::mutex_v2_impl* evt) noexcept
: _mutex(evt)
{
}
~awaiter() noexcept(false)
{
assert(_mutex == nullptr);
if (_mutex != nullptr)
{
throw lock_exception(error_code::not_await_lock);
}
}
bool await_ready() noexcept
{
return false;
}
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>>
bool await_suspend(coroutine_handle<_PromiseT> handler)
{
_PromiseT& promise = handler.promise();
auto* parent = promise.get_state();
_root = parent->get_root();
scoped_lock<detail::mutex_v2_impl::lock_type> lock_(_mutex->_lock);
if (_mutex->try_lock_lockless(_root))
return false;
_state = new detail::state_mutex_t();
(void)_state->on_await_suspend(handler, parent->get_scheduler(), _root);
_mutex->add_wait_list_lockless(_state.get());
return true;
}
scoped_lock_mutex_t await_resume() noexcept
{
detail::mutex_v2_impl* mtx = _mutex;
_mutex = nullptr;
return { std::adopt_lock, mtx, _root };
}
protected:
detail::mutex_v2_impl* _mutex;
counted_ptr<detail::state_mutex_t> _state;
state_base_t* _root = nullptr;
};
inline mutex_t::awaiter mutex_t::lock() const noexcept
{
return { _mutex.get() };
}
inline scoped_lock_mutex_t mutex_t::lock(scheduler_t* sch) const noexcept
{
if (sch != nullptr)
_mutex->lock_until_succeed(sch);
return { std::adopt_lock, _mutex.get(), sch };
}
inline bool mutex_t::try_lock(scheduler_t* sch) const noexcept
{
if (sch == nullptr)
return false;
return _mutex->try_lock(sch);
}
inline void mutex_t::unlock(scheduler_t* sch) const noexcept
{
assert(sch != nullptr);
_mutex->unlock(sch);
}
}
}

View File

@ -18,6 +18,7 @@ RESUMEF_NS
"unlock_more", "unlock_more",
"read_before_write", "read_before_write",
"timer_canceled", "timer_canceled",
"not_await_lock",
}; };
char sz_future_error_buffer[256]; char sz_future_error_buffer[256];

View File

@ -15,7 +15,7 @@ RESUMEF_NS
static const int FREE_VALUE = 0; static const int FREE_VALUE = 0;
static const int LOCKED_VALUE = 1; static const int LOCKED_VALUE = 1;
volatile std::atomic<int> lck; std::atomic<int> lck;
#if _DEBUG #if _DEBUG
std::thread::id owner_thread_id; std::thread::id owner_thread_id;
#endif #endif

View File

@ -11,6 +11,11 @@ RESUMEF_NS
delete this; delete this;
} }
state_base_t* state_base_t::get_parent() const noexcept
{
return nullptr;
}
void state_future_t::destroy_deallocate() void state_future_t::destroy_deallocate()
{ {
size_t _Size = this->_alloc_size; size_t _Size = this->_alloc_size;
@ -88,6 +93,11 @@ RESUMEF_NS
return true; return true;
} }
state_base_t* state_future_t::get_parent() const noexcept
{
return _parent;
}
void state_future_t::resume() void state_future_t::resume()
{ {
std::unique_lock<lock_type> __guard(_mtx); std::unique_lock<lock_type> __guard(_mtx);

View File

@ -33,6 +33,7 @@ RESUMEF_NS
public: public:
virtual void resume() = 0; virtual void resume() = 0;
virtual bool has_handler() const noexcept = 0; virtual bool has_handler() const noexcept = 0;
virtual state_base_t* get_parent() const noexcept;
void set_scheduler(scheduler_t* sch) void set_scheduler(scheduler_t* sch)
{ {
@ -42,6 +43,18 @@ RESUMEF_NS
{ {
return _coro; return _coro;
} }
state_base_t* get_root() const noexcept
{
state_base_t* root = const_cast<state_base_t*>(this);
state_base_t* next = root->get_parent();
while (next != nullptr)
{
root = next;
next = next->get_parent();
}
return root;
}
}; };
struct state_generator_t : public state_base_t struct state_generator_t : public state_base_t
@ -125,6 +138,7 @@ RESUMEF_NS
virtual void destroy_deallocate() override; virtual void destroy_deallocate() override;
virtual void resume() override; virtual void resume() override;
virtual bool has_handler() const noexcept override; virtual bool has_handler() const noexcept override;
virtual state_base_t* get_parent() const noexcept override;
inline bool is_ready() const noexcept inline bool is_ready() const noexcept
{ {
@ -149,10 +163,6 @@ RESUMEF_NS
return _parent ? _parent->get_scheduler() : _scheduler; return _parent ? _parent->get_scheduler() : _scheduler;
} }
inline state_base_t * get_parent() const noexcept
{
return _parent;
}
inline uint32_t get_alloc_size() const noexcept inline uint32_t get_alloc_size() const noexcept
{ {
return _alloc_size; return _alloc_size;

View File

@ -19,7 +19,7 @@ future_t<> test_mutex_pop(size_t idx)
for (size_t i = 0; i < 10; ++i) for (size_t i = 0; i < 10; ++i)
{ {
co_await resumf_guard_lock(g_lock); auto _locker = co_await g_lock.lock();
if (g_queue.size() > 0) if (g_queue.size() > 0)
{ {
@ -32,14 +32,15 @@ future_t<> test_mutex_pop(size_t idx)
} }
} }
future_t<> test_mutex_push() future_t<> test_mutex_push(size_t idx)
{ {
using namespace std::chrono; using namespace std::chrono;
for (size_t i = 0; i < 10; ++i) for (size_t i = 0; i < 10; ++i)
{ {
co_await resumf_guard_lock(g_lock); auto _locker = co_await g_lock.lock();
g_queue.push_back(i); g_queue.push_back(i);
std::cout << i << " on " << idx << std::endl;
co_await sleep_for(500ms); co_await sleep_for(500ms);
} }
@ -47,7 +48,7 @@ future_t<> test_mutex_push()
void resumable_main_mutex() void resumable_main_mutex()
{ {
go test_mutex_push(); go test_mutex_push(0);
go test_mutex_pop(1); go test_mutex_pop(1);
this_scheduler()->run_until_notask(); this_scheduler()->run_until_notask();

View File

@ -47,7 +47,8 @@ int main(int argc, const char* argv[])
//resumable_main_event(); //resumable_main_event();
//resumable_main_event_timeout(); //resumable_main_event_timeout();
//resumable_main_sleep(); //resumable_main_sleep();
//return 0; resumable_main_mutex();
return 0;
//if (argc > 1) //if (argc > 1)
// resumable_main_benchmark_asio_client(atoi(argv[1])); // resumable_main_benchmark_asio_client(atoi(argv[1]));

View File

@ -183,7 +183,8 @@
<ClCompile Include="..\benchmark\benchmark_channel_passing_next.cpp" /> <ClCompile Include="..\benchmark\benchmark_channel_passing_next.cpp" />
<ClCompile Include="..\librf\src\event_v1.cpp" /> <ClCompile Include="..\librf\src\event_v1.cpp" />
<ClCompile Include="..\librf\src\event_v2.cpp" /> <ClCompile Include="..\librf\src\event_v2.cpp" />
<ClCompile Include="..\librf\src\mutex.cpp" /> <ClCompile Include="..\librf\src\mutex_v1.cpp" />
<ClCompile Include="..\librf\src\mutex_v2.cpp" />
<ClCompile Include="..\librf\src\rf_task.cpp" /> <ClCompile Include="..\librf\src\rf_task.cpp" />
<ClCompile Include="..\librf\src\scheduler.cpp" /> <ClCompile Include="..\librf\src\scheduler.cpp" />
<ClCompile Include="..\librf\src\sleep.cpp" /> <ClCompile Include="..\librf\src\sleep.cpp" />
@ -233,6 +234,8 @@
<ClInclude Include="..\librf\src\future.h" /> <ClInclude Include="..\librf\src\future.h" />
<ClInclude Include="..\librf\src\generator.h" /> <ClInclude Include="..\librf\src\generator.h" />
<ClInclude Include="..\librf\src\intrusive_link_queue.h" /> <ClInclude Include="..\librf\src\intrusive_link_queue.h" />
<ClInclude Include="..\librf\src\mutex_v1.h" />
<ClInclude Include="..\librf\src\mutex_v2.h" />
<ClInclude Include="..\librf\src\promise.h" /> <ClInclude Include="..\librf\src\promise.h" />
<ClInclude Include="..\librf\src\mutex.h" /> <ClInclude Include="..\librf\src\mutex.h" />
<ClInclude Include="..\librf\src\rf_task.h" /> <ClInclude Include="..\librf\src\rf_task.h" />
@ -260,6 +263,7 @@
<None Include="..\librf\src\event_v2.inl" /> <None Include="..\librf\src\event_v2.inl" />
<None Include="..\librf\src\exception.inl" /> <None Include="..\librf\src\exception.inl" />
<None Include="..\librf\src\macro_def.inl" /> <None Include="..\librf\src\macro_def.inl" />
<None Include="..\librf\src\mutex_v2.inl" />
<None Include="..\librf\src\promise.inl" /> <None Include="..\librf\src\promise.inl" />
<None Include="..\librf\src\state.inl" /> <None Include="..\librf\src\state.inl" />
<None Include="..\librf\src\type_concept.inl" /> <None Include="..\librf\src\type_concept.inl" />

View File

@ -25,9 +25,6 @@
<ClCompile Include="librf.cpp"> <ClCompile Include="librf.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\librf\src\mutex.cpp">
<Filter>librf\src</Filter>
</ClCompile>
<ClCompile Include="..\librf\src\rf_task.cpp"> <ClCompile Include="..\librf\src\rf_task.cpp">
<Filter>librf\src</Filter> <Filter>librf\src</Filter>
</ClCompile> </ClCompile>
@ -121,6 +118,12 @@
<ClCompile Include="..\librf\src\when_v2.cpp"> <ClCompile Include="..\librf\src\when_v2.cpp">
<Filter>librf\src</Filter> <Filter>librf\src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\librf\src\mutex_v1.cpp">
<Filter>librf\src</Filter>
</ClCompile>
<ClCompile Include="..\librf\src\mutex_v2.cpp">
<Filter>librf\src</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\librf\librf.h"> <ClInclude Include="..\librf\librf.h">
@ -228,6 +231,12 @@
<ClInclude Include="..\librf\src\when_v2.h"> <ClInclude Include="..\librf\src\when_v2.h">
<Filter>librf\src</Filter> <Filter>librf\src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\librf\src\mutex_v1.h">
<Filter>librf\src</Filter>
</ClInclude>
<ClInclude Include="..\librf\src\mutex_v2.h">
<Filter>librf\src</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\librf\src\asio_task_1.12.0.inl"> <None Include="..\librf\src\asio_task_1.12.0.inl">
@ -261,5 +270,8 @@
<None Include="..\librf\src\type_concept.inl"> <None Include="..\librf\src\type_concept.inl">
<Filter>librf\src</Filter> <Filter>librf\src</Filter>
</None> </None>
<None Include="..\librf\src\mutex_v2.inl">
<Filter>librf\src</Filter>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>