Browse Source

支持编译为动态库,支持安装脚本

3.0.0
tearshark 2 years ago
parent
commit
54c0ad32b9

+ 2
- 0
.gitignore View File

bin bin
out out
/CMakeSettings.json /CMakeSettings.json
install
lib

+ 21
- 12
CMakeLists.txt View File

option(OPT_KEEP_REAL_SIZE "Keep real size in queue" OFF) option(OPT_KEEP_REAL_SIZE "Keep real size in queue" OFF)
option(OPT_DISABLE_MULT_THREAD "Disable multi-threaded scheduler" OFF) option(OPT_DISABLE_MULT_THREAD "Disable multi-threaded scheduler" OFF)
option(OPT_USE_MIMALLOC "Use mimalloc" OFF) option(OPT_USE_MIMALLOC "Use mimalloc" OFF)
option(OPT_DYNAMIC_LIBRARY "Use shared library" OFF)
option(OPT_DYNAMIC_LIBRARY "Use shared library" ON)
option(CMAKE_ENABLE_UNIT_TEST "Enable unit test" OFF)
if (UNIX) if (UNIX)
if(OPT_USE_MIMALLOC) if(OPT_USE_MIMALLOC)
if(OPT_DISABLE_MULT_THREAD) if(OPT_DISABLE_MULT_THREAD)
set(RESUMEF_DISABLE_MULT_THREAD 1) set(RESUMEF_DISABLE_MULT_THREAD 1)
endif() endif()
if(OPT_DYNAMIC_LIBRARY)
set(RESUMEF_USE_SHARD_LIBRARY 1)
add_compile_definitions("-DRESUMEF_DYNAMIC_EXPORTS=1")
endif()
configure_file( configure_file(
${CMAKE_SOURCE_DIR}/config.h.in ${CMAKE_SOURCE_DIR}/config.h.in
file(GLOB_RECURSE SOURCE_FILES ${CMAKE_SOURCE_DIR}/source/*.*) file(GLOB_RECURSE SOURCE_FILES ${CMAKE_SOURCE_DIR}/source/*.*)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
if(OPT_DYNAMIC_LIBRARY) if(OPT_DYNAMIC_LIBRARY)
${HEADER_FILES} ${HEADER_FILES}
${SOURCE_FILES} ${SOURCE_FILES}
) )
target_compile_definitions(${PROJECT_NAME}
PRIVATE LIBRF_DYNAMIC_EXPORTS=1
)
else() else()
add_library(${PROJECT_NAME} STATIC add_library(${PROJECT_NAME} STATIC
${HEADER_FILES} ${HEADER_FILES}
${SOURCE_FILES} ${SOURCE_FILES}
) )
target_compile_definitions(${PROJECT_NAME}
PRIVATE LIBRF_USE_STATIC_LIBRARY=1
)
endif() endif()
target_include_directories(${PROJECT_NAME} target_include_directories(${PROJECT_NAME}
PUBLIC PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include
) )
include_directories(
${CMAKE_SOURCE_DIR}/modern_cb
)
if(OPT_USE_MIMALLOC) if(OPT_USE_MIMALLOC)
set(LIB_MIMALLOC, "mimalloc") set(LIB_MIMALLOC, "mimalloc")
else() else()
set(LIB_MIMALLOC, "") set(LIB_MIMALLOC, "")
endif() endif()
add_subdirectory(tutorial)
#add_subdirectory(benchmark)
if(CMAKE_ENABLE_UNIT_TEST)
include_directories(
${CMAKE_SOURCE_DIR}/modern_cb
)
add_subdirectory(tutorial)
#add_subdirectory(benchmark)
endif()
include(${CMAKE_SOURCE_DIR}/cmake/install.cmake)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/librf DESTINATION include)

+ 2
- 0
Config.cmake.in View File

include(${CMAKE_CURRENT_LIST_DIR}/SelectDynamicLibrary.cmake)
select_dynamic_library(librf librf/librf.h)

+ 161
- 0
cmake/SelectDynamicLibrary.cmake View File

include(SelectLibraryConfigurations)

macro(_acl_copy_dynamic_library_build_type basename build_type)

if(${build_type} STREQUAL "Debug")
set(_acl_build_type_dir "Debug")
set(_acl_runtime_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG})
elseif(${build_type} STREQUAL "Release")
set(_acl_build_type_dir "Release")
set(_acl_runtime_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE})
elseif(${build_type} STREQUAL "MinSizeRel")
set(_acl_build_type_dir "Release")
set(_acl_runtime_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL})
elseif(${build_type} STREQUAL "RelWithDebInfo")
set(_acl_build_type_dir "Release")
set(_acl_runtime_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO})
endif()
#message(STATUS "_acl_build_type_dir=${CMAKE_CURRENT_LIST_DIR}/../lib/${CMAKE_CXX_PLATFORM_ID}/${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}-${_acl_build_type_dir}")
#message(STATUS "_acl_runtime_output_dir=${_acl_runtime_output_dir}")

find_file(_acl_${basename}_dynamic_binary
NAMES "Acl.${basename}.dll" "Acl.${basename}.so"
PATHS
${CMAKE_CURRENT_LIST_DIR}/../bin/${CMAKE_CXX_PLATFORM_ID}/${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}-${_acl_build_type_dir}
NO_DEFAULT_PATH
)
if(NOT _acl_${basename}_dynamic_binary)
find_file(_acl_${basename}_dynamic_binary
NAMES "${basename}.dll" "${basename}.so"
PATHS
${CMAKE_CURRENT_LIST_DIR}/../bin/${CMAKE_CXX_PLATFORM_ID}/${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}-${_acl_build_type_dir}
NO_DEFAULT_PATH
)
endif()

#message(STATUS "_acl_runtime_dynamic_binary=${_acl_runtime_dynamic_binary}")

if(_acl_${basename}_dynamic_binary)
file(INSTALL ${_acl_${basename}_dynamic_binary} DESTINATION ${_acl_runtime_output_dir})
endif()

unset(_acl_build_type_dir)
unset(_acl_runtime_output_dir)
unset(_acl_${basename}_dynamic_binary CACHE)
endmacro(_acl_copy_dynamic_library_build_type)

macro(_acl_copy_dynamic_library basename)

if(DEFINED CMAKE_CONFIGURATION_TYPES)
foreach(build_type ${CMAKE_CONFIGURATION_TYPES})
_acl_copy_dynamic_library_build_type(${basename} ${build_type})
endforeach(build_type)
elseif(DEFINED CMAKE_BUILD_TYPE)
_acl_copy_dynamic_library_build_type(${basename} ${CMAKE_BUILD_TYPE})
else()
_acl_copy_dynamic_library_build_type(${basename} "Release")
endif()

endmacro(_acl_copy_dynamic_library)


macro(select_dynamic_library basename header)
#message(STATUS "basename=${basename}")
#message(STATUS "header=${header}")

# 如果已经找到了 basename 指定的模块,则只做拷贝运行时的动态库的工作
#message(STATUS "${basename}_FOUND=${${basename}_FOUND}")
if(${basename}_FOUND)
_acl_copy_dynamic_library(${basename})
return()
endif()



# 查找头文件所在的路径
find_path(${basename}_INCLUDE_DIR ${header}
${CMAKE_CURRENT_LIST_DIR}/../include
NO_DEFAULT_PATH
)

# 查找调试版本的库文件所在路径
find_library("${basename}_LIBRARY_DEBUG"
NAMES "Acl.${basename}"
PATHS
${CMAKE_CURRENT_LIST_DIR}/../lib/${CMAKE_CXX_PLATFORM_ID}/${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}-Debug
NO_DEFAULT_PATH
)
if(NOT ${basename}_LIBRARY_DEBUG)
find_library("${basename}_LIBRARY_DEBUG"
NAMES "${basename}"
PATHS
${CMAKE_CURRENT_LIST_DIR}/../lib/${CMAKE_CXX_PLATFORM_ID}/${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}-Debug
NO_DEFAULT_PATH
)
endif()

# 查找发行版本的库文件所在路径
find_library("${basename}_LIBRARY_RELEASE"
NAMES "Acl.${basename}"
PATHS
${CMAKE_CURRENT_LIST_DIR}/../lib/${CMAKE_CXX_PLATFORM_ID}/${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}-Release
NO_DEFAULT_PATH
)
if(NOT ${basename}_LIBRARY_RELEASE)
find_library("${basename}_LIBRARY_RELEASE"
NAMES "${basename}"
PATHS
${CMAKE_CURRENT_LIST_DIR}/../lib/${CMAKE_CXX_PLATFORM_ID}/${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}-Release
NO_DEFAULT_PATH
)
endif()

# 使用cmake内置的 select_library_configurations 函数生成 ${basename}_LIBRARY 字段
select_library_configurations(${basename})



set(${basename}_FOUND FALSE)
if(${basename}_LIBRARY AND ${basename}_INCLUDE_DIR)

set(${basename}_FOUND TRUE)
if(NOT ${basename}_DIR)
set(${basename}_DIR ${CMAKE_CURRENT_LIST_DIR})
endif()

# 做拷贝运行时的动态库到目标目录
_acl_copy_dynamic_library(${basename})

# 创建 basename 指定的导入接口模块
if(NOT TARGET Acl::${basename})

add_library(Acl::${basename} UNKNOWN IMPORTED)
set_target_properties(Acl::${basename} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${${basename}_INCLUDE_DIR}")

set_property(TARGET Acl::${basename} APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Acl::${basename} PROPERTIES
IMPORTED_LOCATION_RELEASE "${${basename}_LIBRARY_RELEASE}")

set_property(TARGET Acl::${basename} APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(Acl::${basename} PROPERTIES
IMPORTED_LOCATION_DEBUG "${${basename}_LIBRARY_DEBUG}")
endif()
endif()



mark_as_advanced(${basename}_DIR)
mark_as_advanced(${basename}_LIBRARY)
mark_as_advanced(${basename}_INCLUDE_DIR)

#message(STATUS "${basename}_DIR=${${basename}_DIR}")
#message(STATUS "${basename}_LIBRARY=${${basename}_LIBRARY}")
#message(STATUS "${basename}_LIBRARY_DEBUG=${${basename}_LIBRARY_DEBUG}")
#message(STATUS "${basename}_LIBRARY_RELEASE=${${basename}_LIBRARY_RELEASE}")
#message(STATUS "${basename}_INCLUDE_DIR=${${basename}_INCLUDE_DIR}")

endmacro(select_dynamic_library)

+ 45
- 0
cmake/install.cmake View File


# Configuration
# Used by cmake to find_package(xxx)
set(PROJECT_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake")

# Add definitions for targets
# Values:
# * Debug: -Dxxx_DEBUG=1
# * Release: -Dxxx_DEBUG=0
# * other: -Dxxx_DEBUG=0
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_DEBUG=$<CONFIG:Debug>)

# Include module with function 'write_basic_package_version_file'
# Configure 'xxxConfigVersion.cmake'
include(CMakePackageConfigHelpers)
write_basic_package_version_file(${VERSION_CONFIG} VERSION ${PACKAGE_VERSION}
COMPATIBILITY SameMajorVersion)

# Configure 'xxxConfig.cmake'
configure_package_config_file(Config.cmake.in ${PROJECT_CONFIG}
INSTALL_DESTINATION cmake/${PROJECT_NAME})

# Targets:
# * <prefix>/lib/Windows/x64-Debug/xxx.lib
# * <prefix>/bin/Windows/x64-Debug/xxx.dll
set(INSTALL_TARGET_PREFIX "${CMAKE_CXX_PLATFORM_ID}/${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}")
install(TARGETS ${PROJECT_NAME}
CONFIGURATIONS Debug
LIBRARY DESTINATION "lib/${INSTALL_TARGET_PREFIX}-Debug"
ARCHIVE DESTINATION "lib/${INSTALL_TARGET_PREFIX}-Debug"
RUNTIME DESTINATION "bin/${INSTALL_TARGET_PREFIX}-Debug"
)
# * <prefix>/lib/Windows/x64-Release/xxx.lib
# * <prefix>/bin/Windows/x64-Release/xxx.dll
install(TARGETS ${PROJECT_NAME}
CONFIGURATIONS Release RelWithDebInfo MinSizeRel
LIBRARY DESTINATION "lib/${INSTALL_TARGET_PREFIX}-Release"
ARCHIVE DESTINATION "lib/${INSTALL_TARGET_PREFIX}-Release"
RUNTIME DESTINATION "bin/${INSTALL_TARGET_PREFIX}-Release"
)

# Config
# * <prefix>/cmake/xxxConfig.cmake
# * <prefix>/cmake/xxxConfigVersion.cmake
install(FILES ${PROJECT_CONFIG} DESTINATION cmake)

+ 1
- 0
include/librf/librf.h View File



#include "src/def.h" #include "src/def.h"
#include "src/macro_def.inl" #include "src/macro_def.inl"
#include "src/exception.inl"
#include "src/counted_ptr.h" #include "src/counted_ptr.h"
#include "src/type_traits.inl" #include "src/type_traits.inl"
#include "src/type_concept.inl" #include "src/type_concept.inl"

+ 0
- 8
include/librf/src/def.h View File

* @brief 版本号。 * @brief 版本号。
*/ */
constexpr size_t _Version = LIB_RESUMEF_VERSION; constexpr size_t _Version = LIB_RESUMEF_VERSION;

/**
* @brief 获得当前线程下的调度器。
*/
scheduler_t* this_scheduler();

} }


#ifndef DOXYGEN_SKIP_PROPERTY #ifndef DOXYGEN_SKIP_PROPERTY
} }
} }


#include "exception.inl"

#endif //DOXYGEN_SKIP_PROPERTY #endif //DOXYGEN_SKIP_PROPERTY

+ 3
- 3
include/librf/src/event_v2.h View File

* @brief 构造一个事件。 * @brief 构造一个事件。
* @param initially 初始是否触发一次信号。 * @param initially 初始是否触发一次信号。
*/ */
event_t(bool initially = false);
LIBRF_API event_t(bool initially = false);


/** /**
* @brief 构造一个无效的事件。 * @brief 构造一个无效的事件。
* @details 如果用于后续保存另外一个事件,则应当使用此构造函数,便于节省一次不必要的内部初始化。 * @details 如果用于后续保存另外一个事件,则应当使用此构造函数,便于节省一次不必要的内部初始化。
*/ */
event_t(std::adopt_lock_t);
LIBRF_API event_t(std::adopt_lock_t);


/** /**
* @brief 采用shared_ptr<>来保存内部的事件实现。故不必担心正在被等待的协程,因为事件提前销毁而出现异常。 * @brief 采用shared_ptr<>来保存内部的事件实现。故不必担心正在被等待的协程,因为事件提前销毁而出现异常。
*/ */
~event_t();
LIBRF_API ~event_t();


/** /**
* @brief 向所有正在等待的协程触发一次信号。 * @brief 向所有正在等待的协程触发一次信号。

+ 12
- 12
include/librf/src/event_v2.inl View File



struct event_v2_impl : public std::enable_shared_from_this<event_v2_impl> struct event_v2_impl : public std::enable_shared_from_this<event_v2_impl>
{ {
event_v2_impl(bool initially) noexcept;
~event_v2_impl();
LIBRF_API event_v2_impl(bool initially) noexcept;
LIBRF_API ~event_v2_impl();


bool is_signaled() const noexcept bool is_signaled() const noexcept
{ {
{ {
_counter.store(0, std::memory_order_release); _counter.store(0, std::memory_order_release);
} }
void signal_all() noexcept;
void signal() noexcept;
LIBRF_API void signal_all() noexcept;
LIBRF_API void signal() noexcept;


public: public:
static constexpr bool USE_SPINLOCK = true; static constexpr bool USE_SPINLOCK = true;


struct state_event_base_t : public state_base_t struct state_event_base_t : public state_base_t
{ {
virtual void resume() override;
virtual bool has_handler() const noexcept override;
LIBRF_API virtual void resume() override;
LIBRF_API virtual bool has_handler() const noexcept override;


virtual void on_cancel() noexcept = 0; virtual void on_cancel() noexcept = 0;
virtual bool on_notify(event_v2_impl* eptr) = 0; virtual bool on_notify(event_v2_impl* eptr) = 0;
: _value(&val) : _value(&val)
{} {}


virtual void on_cancel() noexcept override;
virtual bool on_notify(event_v2_impl* eptr) override;
virtual bool on_timeout() override;
LIBRF_API virtual void on_cancel() noexcept override;
LIBRF_API virtual bool on_notify(event_v2_impl* eptr) override;
LIBRF_API virtual bool on_timeout() override;
protected: protected:
//_value引用awaitor保存的值,这样可以尽可能减少创建state的可能。而不必进入没有state就没有value实体被用于返回。 //_value引用awaitor保存的值,这样可以尽可能减少创建state的可能。而不必进入没有state就没有value实体被用于返回。
//在调用on_notify()或on_timeout()任意之一后,置为nullptr。 //在调用on_notify()或on_timeout()任意之一后,置为nullptr。
, _value(&val) , _value(&val)
{} {}


virtual void on_cancel() noexcept override;
virtual bool on_notify(event_v2_impl* eptr) override;
virtual bool on_timeout() override;
LIBRF_API virtual void on_cancel() noexcept override;
LIBRF_API virtual bool on_notify(event_v2_impl* eptr) override;
LIBRF_API virtual bool on_timeout() override;


std::atomic<intptr_t> _counter; std::atomic<intptr_t> _counter;
protected: protected:

+ 1
- 2
include/librf/src/exception.inl View File

/** /**
* @brief 通过错误码获得错误描述字符串。 * @brief 通过错误码获得错误描述字符串。
*/ */
const char* get_error_string(error_code fe, const char* classname);
LIBRF_API const char* get_error_string(error_code fe, const char* classname);


/** /**
* @brief 在操作future_t<>时产生的异常。 * @brief 在操作future_t<>时产生的异常。
*/ */
const char* get_error_string(error_code fe, const char* classname);
struct future_exception : std::logic_error struct future_exception : std::logic_error
{ {
error_code _error; error_code _error;

+ 2
- 2
include/librf/src/macro_def.inl View File

#endif // unlikely #endif // unlikely
#endif // defined(__clang__) || defined(__GNUC__) #endif // defined(__clang__) || defined(__GNUC__)


#ifdef RESUMEF_USE_SHARD_LIBRARY
#ifndef LIBRF_USE_STATIC_LIBRARY
# if _WIN32 # if _WIN32
# ifdef RESUMEF_DYNAMIC_EXPORTS
# ifdef LIBRF_DYNAMIC_EXPORTS
# define LIBRF_API __declspec(dllexport) # define LIBRF_API __declspec(dllexport)
# else //RESUMEF_DYNAMIC_EXPORTS # else //RESUMEF_DYNAMIC_EXPORTS
# define LIBRF_API __declspec(dllimport) # define LIBRF_API __declspec(dllimport)

+ 3
- 3
include/librf/src/mutex_v2.h View File

> >
static void unlock(void* unique_address, _Mtxs&... mtxs); static void unlock(void* unique_address, _Mtxs&... mtxs);


mutex_t();
LIBRF_API mutex_t();


/** /**
* @brief 构造一个无效的mutex_t。 * @brief 构造一个无效的mutex_t。
*/ */
mutex_t(std::adopt_lock_t) noexcept;
~mutex_t() noexcept;
LIBRF_API mutex_t(std::adopt_lock_t) noexcept;
LIBRF_API ~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;

+ 13
- 13
include/librf/src/mutex_v2.inl View File

: _value(&val) : _value(&val)
{} {}


virtual void resume() override;
virtual bool has_handler() const noexcept override;
virtual state_base_t* get_parent() const noexcept override;
LIBRF_API virtual void resume() override;
LIBRF_API virtual bool has_handler() const noexcept override;
LIBRF_API virtual state_base_t* get_parent() const noexcept override;


void on_cancel() noexcept;
bool on_notify(mutex_v2_impl* eptr);
bool on_timeout();
LIBRF_API void on_cancel() noexcept;
LIBRF_API bool on_notify(mutex_v2_impl* eptr);
LIBRF_API bool on_timeout();


void add_timeout_timer(std::chrono::system_clock::time_point tp);
LIBRF_API void add_timeout_timer(std::chrono::system_clock::time_point tp);


inline void on_await_suspend(coroutine_handle<> handler, scheduler_t* sch, state_base_t* root) noexcept inline void on_await_suspend(coroutine_handle<> handler, scheduler_t* sch, state_base_t* root) noexcept
{ {
return _owner.load(std::memory_order_relaxed); return _owner.load(std::memory_order_relaxed);
} }


bool try_lock(void* sch); //内部加锁
bool try_lock_until(clock_type::time_point tp, void* sch); //内部加锁
bool unlock(void* sch); //内部加锁
void lock_until_succeed(void* sch); //内部加锁
LIBRF_API bool try_lock(void* sch); //内部加锁
LIBRF_API bool try_lock_until(clock_type::time_point tp, void* sch); //内部加锁
LIBRF_API bool unlock(void* sch); //内部加锁
LIBRF_API void lock_until_succeed(void* sch); //内部加锁
public: public:
static constexpr bool USE_SPINLOCK = true; static constexpr bool USE_SPINLOCK = true;


using state_mutex_ptr = counted_ptr<state_mutex_t>; using state_mutex_ptr = counted_ptr<state_mutex_t>;
using wait_queue_type = std::list<state_mutex_ptr>; 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); //内部不加锁,加锁由外部来进行
LIBRF_API bool try_lock_lockless(void* sch) noexcept; //内部不加锁,加锁由外部来进行
LIBRF_API void add_wait_list_lockless(state_mutex_t* state); //内部不加锁,加锁由外部来进行


lock_type _lock; //保证访问本对象是线程安全的 lock_type _lock; //保证访问本对象是线程安全的
private: private:

+ 3
- 3
include/librf/src/rf_task.h View File

*/ */
struct task_t struct task_t
{ {
task_t() noexcept;
virtual ~task_t();
LIBRF_API task_t() noexcept;
LIBRF_API virtual ~task_t();


/** /**
* @brief 获取stop_source,第一次获取时,会生成一个有效的stop_source。 * @brief 获取stop_source,第一次获取时,会生成一个有效的stop_source。
* @return stop_source * @return stop_source
*/ */
const stop_source & get_stop_source();
LIBRF_API const stop_source & get_stop_source();


/** /**
* @brief 获取一个跟stop_source绑定的,新的stop_token。 * @brief 获取一个跟stop_source绑定的,新的stop_token。

+ 19
- 14
include/librf/src/scheduler.h View File



namespace librf namespace librf
{ {
/**
* @brief 获得当前线程下的调度器。
*/
LIBRF_API scheduler_t* this_scheduler();

/** /**
* @brief 协程调度器。 * @brief 协程调度器。
* @details librf的设计原则之一,就是要将协程绑定在固定的调度器里执行。 * @details librf的设计原则之一,就是要将协程绑定在固定的调度器里执行。


timer_mgr_ptr _timer; timer_mgr_ptr _timer;


task_t* new_task(task_t* task);
LIBRF_API task_t* new_task(task_t* task);
//void cancel_all_task_(); //void cancel_all_task_();
public: public:
/** /**
* @details 这是协程调度器提供的主要接口。同一个调度器非线程安全,不可重入。\n * @details 这是协程调度器提供的主要接口。同一个调度器非线程安全,不可重入。\n
* 调用者要保证此函数始终在同一个线程里调用。 * 调用者要保证此函数始终在同一个线程里调用。
*/ */
bool run_one_batch();
LIBRF_API bool run_one_batch();


/** /**
* @brief 循环运行所有的协程,直到所有协程都运行完成。 * @brief 循环运行所有的协程,直到所有协程都运行完成。
* @details 通常用于测试代码。 * @details 通常用于测试代码。
*/ */
void run_until_notask();
LIBRF_API void run_until_notask();


//void break_all(); //void break_all();


} }


#ifndef DOXYGEN_SKIP_PROPERTY #ifndef DOXYGEN_SKIP_PROPERTY
void add_generator(state_base_t* sptr);
void del_final(state_base_t* sptr);
std::unique_ptr<task_t> del_switch(state_base_t* sptr);
void add_switch(std::unique_ptr<task_t> task);
task_t* find_task(state_base_t* sptr) const noexcept;
LIBRF_API void add_generator(state_base_t* sptr);
LIBRF_API void del_final(state_base_t* sptr);
LIBRF_API std::unique_ptr<task_t> del_switch(state_base_t* sptr);
LIBRF_API void add_switch(std::unique_ptr<task_t> task);
LIBRF_API task_t* find_task(state_base_t* sptr) const noexcept;


friend struct local_scheduler_t; friend struct local_scheduler_t;
protected: protected:
scheduler_t();
LIBRF_API scheduler_t();
public: public:
~scheduler_t();
LIBRF_API ~scheduler_t();


scheduler_t(scheduler_t&& right_) = delete; scheduler_t(scheduler_t&& right_) = delete;
scheduler_t& operator = (scheduler_t&& right_) = delete; scheduler_t& operator = (scheduler_t&& right_) = delete;
scheduler_t(const scheduler_t&) = delete; scheduler_t(const scheduler_t&) = delete;
scheduler_t& operator = (const scheduler_t&) = delete; scheduler_t& operator = (const scheduler_t&) = delete;


static scheduler_t g_scheduler;
LIBRF_API static scheduler_t g_scheduler;
#endif //DOXYGEN_SKIP_PROPERTY #endif //DOXYGEN_SKIP_PROPERTY
}; };


/** /**
* @brief 尽可能的创建一个线程相关的调度器。 * @brief 尽可能的创建一个线程相关的调度器。
*/ */
local_scheduler_t();
LIBRF_API local_scheduler_t();


/** /**
* @brief 将指定的调度器绑定到当前线程上。 * @brief 将指定的调度器绑定到当前线程上。
*/ */
local_scheduler_t(scheduler_t & sch) noexcept;
LIBRF_API local_scheduler_t(scheduler_t & sch) noexcept;


/** /**
* @brief 如果当前线程绑定的调度器由local_scheduler_t所创建,则会销毁调度器,并解绑线程。 * @brief 如果当前线程绑定的调度器由local_scheduler_t所创建,则会销毁调度器,并解绑线程。
*/ */
~local_scheduler_t();
LIBRF_API ~local_scheduler_t();


local_scheduler_t(local_scheduler_t&& right_) = delete; local_scheduler_t(local_scheduler_t&& right_) = delete;
local_scheduler_t& operator = (local_scheduler_t&& right_) = delete; local_scheduler_t& operator = (local_scheduler_t&& right_) = delete;

+ 1
- 1
include/librf/src/sleep.h View File

* @return [co_await] void * @return [co_await] void
* @throw timer_canceled_exception 如果定时器被取消,则抛此异常。 * @throw timer_canceled_exception 如果定时器被取消,则抛此异常。
*/ */
future_t<> sleep_until_(std::chrono::system_clock::time_point tp_, scheduler_t& scheduler_);
LIBRF_API future_t<> sleep_until_(std::chrono::system_clock::time_point tp_, scheduler_t& scheduler_);


/** /**
* @brief 协程专用的睡眠功能。 * @brief 协程专用的睡眠功能。

+ 16
- 16
include/librf/src/state.h View File

// 二、没有co_await操作,直接加入到了调度器里,则_coro在初始时为nullptr。调度器需要特殊处理此种情况。 // 二、没有co_await操作,直接加入到了调度器里,则_coro在初始时为nullptr。调度器需要特殊处理此种情况。
coroutine_handle<> _coro; coroutine_handle<> _coro;


virtual ~state_base_t();
LIBRF_API virtual ~state_base_t();
private: private:
virtual void destroy_deallocate();
LIBRF_API virtual void destroy_deallocate();
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;
LIBRF_API virtual state_base_t* get_parent() const noexcept;


void set_scheduler(scheduler_t* sch) noexcept void set_scheduler(scheduler_t* sch) noexcept
{ {
struct state_generator_t : public state_base_t struct state_generator_t : public state_base_t
{ {
private: private:
virtual void destroy_deallocate() override;
LIBRF_API virtual void destroy_deallocate() override;
state_generator_t() = default; state_generator_t() = default;
public: public:
virtual void resume() override;
virtual bool has_handler() const noexcept override;
LIBRF_API virtual void resume() override;
LIBRF_API virtual bool has_handler() const noexcept override;


bool switch_scheduler_await_suspend(scheduler_t* sch);
LIBRF_API bool switch_scheduler_await_suspend(scheduler_t* sch);


void set_initial_suspend(coroutine_handle<> handler) noexcept void set_initial_suspend(coroutine_handle<> handler) noexcept
{ {
return new(_Ptr) state_generator_t(); return new(_Ptr) state_generator_t();
} }
#endif #endif
static state_generator_t* _Alloc_state();
LIBRF_API static state_generator_t* _Alloc_state();
}; };


/** /**
_is_future = !awaitor; _is_future = !awaitor;
} }
public: public:
virtual void destroy_deallocate() override;
virtual void resume() override;
virtual bool has_handler() const noexcept override;
virtual state_base_t* get_parent() const noexcept override;
LIBRF_API virtual void destroy_deallocate() override;
LIBRF_API virtual void resume() override;
LIBRF_API virtual bool has_handler() const noexcept override;
LIBRF_API virtual state_base_t* get_parent() const noexcept override;


inline bool is_ready() const noexcept inline bool is_ready() const noexcept
{ {
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>>
void future_await_suspend(coroutine_handle<_PromiseT> handler); void future_await_suspend(coroutine_handle<_PromiseT> handler);


bool switch_scheduler_await_suspend(scheduler_t* sch);
LIBRF_API bool switch_scheduler_await_suspend(scheduler_t* sch);


template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>>
void promise_initial_suspend(coroutine_handle<_PromiseT> handler); void promise_initial_suspend(coroutine_handle<_PromiseT> handler);
private: private:
explicit state_t(bool awaitor) noexcept :state_future_t(awaitor) {} explicit state_t(bool awaitor) noexcept :state_future_t(awaitor) {}
public: public:
void future_await_resume();
LIBRF_API void future_await_resume();
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>>
void promise_yield_value(_PromiseT* promise); void promise_yield_value(_PromiseT* promise);


void set_exception(std::exception_ptr e);
void set_value();
LIBRF_API void set_exception(std::exception_ptr e);
LIBRF_API void set_value();


template<class _Exp> template<class _Exp>
inline void throw_exception(_Exp e) inline void throw_exception(_Exp e)

+ 7
- 7
include/librf/src/timer.h View File

typedef std::multimap<clock_type::time_point, timer_target_ptr> timer_map_type; typedef std::multimap<clock_type::time_point, timer_target_ptr> timer_map_type;
#endif #endif
public: public:
timer_manager();
~timer_manager();
LIBRF_API timer_manager();
LIBRF_API ~timer_manager();


template<class _Rep, class _Period, class _Cb> template<class _Rep, class _Period, class _Cb>
timer_target_ptr add(const std::chrono::duration<_Rep, _Period> & dt_, _Cb && cb_) timer_target_ptr add(const std::chrono::duration<_Rep, _Period> & dt_, _Cb && cb_)
return{ this, add(tp_, std::forward<_Cb>(cb_)) }; return{ this, add(tp_, std::forward<_Cb>(cb_)) };
} }


bool stop(const timer_target_ptr & sptr);
LIBRF_API bool stop(const timer_target_ptr & sptr);


inline bool empty() const inline bool empty() const
{ {
return _runing_timers.empty() && _added_timers.empty(); return _runing_timers.empty() && _added_timers.empty();
} }
void clear();
void update();
LIBRF_API void clear();
LIBRF_API void update();


#ifndef DOXYGEN_SKIP_PROPERTY #ifndef DOXYGEN_SKIP_PROPERTY
template<class _Cb> template<class _Cb>
timer_vector_type _added_timers; timer_vector_type _added_timers;
timer_map_type _runing_timers; timer_map_type _runing_timers;


timer_target_ptr add_(const timer_target_ptr & sptr);
static void call_target_(const timer_target_ptr & sptr, bool canceld);
LIBRF_API timer_target_ptr add_(const timer_target_ptr & sptr);
LIBRF_API static void call_target_(const timer_target_ptr & sptr, bool canceld);
#endif #endif
}; };



+ 6
- 6
include/librf/src/when_v2.h View File

{ {
struct state_when_t : public state_base_t struct state_when_t : public state_base_t
{ {
state_when_t(intptr_t counter_);
LIBRF_API state_when_t(intptr_t counter_);


virtual void resume() override;
virtual bool has_handler() const noexcept override;
LIBRF_API virtual void resume() override;
LIBRF_API virtual bool has_handler() const noexcept override;


void on_cancel() noexcept;
bool on_notify_one();
bool on_timeout();
LIBRF_API void on_cancel() noexcept;
LIBRF_API bool on_notify_one();
LIBRF_API bool on_timeout();


//将自己加入到通知链表里 //将自己加入到通知链表里
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>>

+ 15
- 15
source/event_v2.cpp View File

{ {
namespace detail namespace detail
{ {
void state_event_base_t::resume()
LIBRF_API void state_event_base_t::resume()
{ {
coroutine_handle<> handler = _coro; coroutine_handle<> handler = _coro;
if (handler) if (handler)
} }
} }


bool state_event_base_t::has_handler() const noexcept
LIBRF_API bool state_event_base_t::has_handler() const noexcept
{ {
return (bool)_coro; return (bool)_coro;
} }


void state_event_t::on_cancel() noexcept
LIBRF_API void state_event_t::on_cancel() noexcept
{ {
event_v2_impl** oldValue = _value.load(std::memory_order_acquire); event_v2_impl** oldValue = _value.load(std::memory_order_acquire);
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
} }
} }


bool state_event_t::on_notify(event_v2_impl* eptr)
LIBRF_API bool state_event_t::on_notify(event_v2_impl* eptr)
{ {
event_v2_impl** oldValue = _value.load(std::memory_order_acquire); event_v2_impl** oldValue = _value.load(std::memory_order_acquire);
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
return false; return false;
} }


bool state_event_t::on_timeout()
LIBRF_API bool state_event_t::on_timeout()
{ {
event_v2_impl** oldValue = _value.load(std::memory_order_acquire); event_v2_impl** oldValue = _value.load(std::memory_order_acquire);
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))






void state_event_all_t::on_cancel() noexcept
LIBRF_API void state_event_all_t::on_cancel() noexcept
{ {
intptr_t oldValue = _counter.load(std::memory_order_acquire); intptr_t oldValue = _counter.load(std::memory_order_acquire);
if (oldValue >= 0 && _counter.compare_exchange_strong(oldValue, -1, std::memory_order_acq_rel)) if (oldValue >= 0 && _counter.compare_exchange_strong(oldValue, -1, std::memory_order_acq_rel))
} }
} }


bool state_event_all_t::on_notify(event_v2_impl*)
LIBRF_API bool state_event_all_t::on_notify(event_v2_impl*)
{ {
intptr_t oldValue = _counter.load(std::memory_order_acquire); intptr_t oldValue = _counter.load(std::memory_order_acquire);
if (oldValue <= 0) return false; if (oldValue <= 0) return false;
return oldValue >= 1; return oldValue >= 1;
} }


bool state_event_all_t::on_timeout()
LIBRF_API bool state_event_all_t::on_timeout()
{ {
intptr_t oldValue = _counter.load(std::memory_order_acquire); intptr_t oldValue = _counter.load(std::memory_order_acquire);
if (oldValue >= 0 && _counter.compare_exchange_strong(oldValue, -1, std::memory_order_acq_rel)) if (oldValue >= 0 && _counter.compare_exchange_strong(oldValue, -1, std::memory_order_acq_rel))






event_v2_impl::event_v2_impl(bool initially) noexcept
LIBRF_API event_v2_impl::event_v2_impl(bool initially) noexcept
: _counter(initially ? 1 : 0) : _counter(initially ? 1 : 0)
{ {
} }
list.clear(); list.clear();
} }


event_v2_impl::~event_v2_impl()
LIBRF_API event_v2_impl::~event_v2_impl()
{ {
clear_list(_wait_awakes); clear_list(_wait_awakes);
} }


void event_v2_impl::signal_all() noexcept
LIBRF_API void event_v2_impl::signal_all() noexcept
{ {
scoped_lock<lock_type> lock_(_lock); scoped_lock<lock_type> lock_(_lock);


} }
} }


void event_v2_impl::signal() noexcept
LIBRF_API void event_v2_impl::signal() noexcept
{ {
scoped_lock<lock_type> lock_(_lock); scoped_lock<lock_type> lock_(_lock);


} }
} }


event_t::event_t(bool initially)
LIBRF_API event_t::event_t(bool initially)
:_event(std::make_shared<detail::event_v2_impl>(initially)) :_event(std::make_shared<detail::event_v2_impl>(initially))
{ {
} }


event_t::event_t(std::adopt_lock_t)
LIBRF_API event_t::event_t(std::adopt_lock_t)
{ {
} }


event_t::~event_t()
LIBRF_API event_t::~event_t()
{ {
} }
} }

+ 16
- 16
source/mutex_v2.cpp View File

{ {
namespace detail namespace detail
{ {
void state_mutex_t::resume()
LIBRF_API void state_mutex_t::resume()
{ {
coroutine_handle<> handler = _coro; coroutine_handle<> handler = _coro;
if (handler) if (handler)
} }
} }


bool state_mutex_t::has_handler() const noexcept
LIBRF_API bool state_mutex_t::has_handler() const noexcept
{ {
return (bool)_coro; return (bool)_coro;
} }
state_base_t* state_mutex_t::get_parent() const noexcept
LIBRF_API state_base_t* state_mutex_t::get_parent() const noexcept
{ {
return _root; return _root;
} }




void state_mutex_t::on_cancel() noexcept
LIBRF_API void state_mutex_t::on_cancel() noexcept
{ {
mutex_v2_impl** oldValue = _value.load(std::memory_order_acquire); mutex_v2_impl** oldValue = _value.load(std::memory_order_acquire);
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
} }
} }


bool state_mutex_t::on_notify(mutex_v2_impl* eptr)
LIBRF_API bool state_mutex_t::on_notify(mutex_v2_impl* eptr)
{ {
assert(eptr != nullptr); assert(eptr != nullptr);


return false; return false;
} }


bool state_mutex_t::on_timeout()
LIBRF_API bool state_mutex_t::on_timeout()
{ {
mutex_v2_impl** oldValue = _value.load(std::memory_order_acquire); mutex_v2_impl** oldValue = _value.load(std::memory_order_acquire);
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
return false; return false;
} }


void state_mutex_t::add_timeout_timer(std::chrono::system_clock::time_point tp)
LIBRF_API void state_mutex_t::add_timeout_timer(std::chrono::system_clock::time_point tp)
{ {
this->_thandler = this->_scheduler->timer()->add_handler(tp, this->_thandler = this->_scheduler->timer()->add_handler(tp,
[st = counted_ptr<state_mutex_t>{ this }](bool canceld) [st = counted_ptr<state_mutex_t>{ this }](bool canceld)






void mutex_v2_impl::lock_until_succeed(void* sch)
LIBRF_API void mutex_v2_impl::lock_until_succeed(void* sch)
{ {
assert(sch != nullptr); assert(sch != nullptr);


} }
} }


bool mutex_v2_impl::try_lock(void* sch)
LIBRF_API bool mutex_v2_impl::try_lock(void* sch)
{ {
assert(sch != nullptr); assert(sch != nullptr);


return try_lock_lockless(sch); return try_lock_lockless(sch);
} }


bool mutex_v2_impl::try_lock_until(clock_type::time_point tp, void* sch)
LIBRF_API bool mutex_v2_impl::try_lock_until(clock_type::time_point tp, void* sch)
{ {
assert(sch != nullptr); assert(sch != nullptr);


return false; return false;
} }


bool mutex_v2_impl::try_lock_lockless(void* sch) noexcept
LIBRF_API bool mutex_v2_impl::try_lock_lockless(void* sch) noexcept
{ {
assert(sch != nullptr); assert(sch != nullptr);


return false; return false;
} }


bool mutex_v2_impl::unlock(void* sch)
LIBRF_API bool mutex_v2_impl::unlock(void* sch)
{ {
assert(sch != nullptr); assert(sch != nullptr);


return false; return false;
} }


void mutex_v2_impl::add_wait_list_lockless(state_mutex_t* state)
LIBRF_API void mutex_v2_impl::add_wait_list_lockless(state_mutex_t* state)
{ {
assert(state != nullptr); assert(state != nullptr);


} }
} }


mutex_t::mutex_t()
LIBRF_API mutex_t::mutex_t()
: _mutex(std::make_shared<detail::mutex_v2_impl>()) : _mutex(std::make_shared<detail::mutex_v2_impl>())
{ {
} }


mutex_t::mutex_t(std::adopt_lock_t) noexcept
LIBRF_API mutex_t::mutex_t(std::adopt_lock_t) noexcept
{ {
} }


mutex_t::~mutex_t() noexcept
LIBRF_API mutex_t::~mutex_t() noexcept
{ {
} }
} }

+ 3
- 3
source/rf_task.cpp View File



namespace librf namespace librf
{ {
task_t::task_t() noexcept
LIBRF_API task_t::task_t() noexcept
: _stop(nostopstate) : _stop(nostopstate)
{ {
} }


task_t::~task_t()
LIBRF_API task_t::~task_t()
{ {
} }


const stop_source & task_t::get_stop_source()
LIBRF_API const stop_source & task_t::get_stop_source()
{ {
_stop.make_sure_possible(); _stop.make_sure_possible();
return _stop; return _stop;

+ 12
- 12
source/scheduler.cpp View File



char sz_future_error_buffer[256]; char sz_future_error_buffer[256];


const char * get_error_string(error_code fe, const char * classname)
LIBRF_API const char * get_error_string(error_code fe, const char * classname)
{ {
if (classname) if (classname)
{ {
thread_local scheduler_t * th_scheduler_ptr = nullptr; thread_local scheduler_t * th_scheduler_ptr = nullptr;


//获得当前线程下的调度器 //获得当前线程下的调度器
scheduler_t * this_scheduler()
LIBRF_API scheduler_t * this_scheduler()
{ {
return th_scheduler_ptr ? th_scheduler_ptr : &scheduler_t::g_scheduler; return th_scheduler_ptr ? th_scheduler_ptr : &scheduler_t::g_scheduler;
} }


local_scheduler_t::local_scheduler_t()
LIBRF_API local_scheduler_t::local_scheduler_t()
{ {
if (th_scheduler_ptr == nullptr) if (th_scheduler_ptr == nullptr)
{ {
} }
} }


local_scheduler_t::local_scheduler_t(scheduler_t& sch) noexcept
LIBRF_API local_scheduler_t::local_scheduler_t(scheduler_t& sch) noexcept
{ {
if (th_scheduler_ptr == nullptr) if (th_scheduler_ptr == nullptr)
{ {
_scheduler_ptr = nullptr; _scheduler_ptr = nullptr;
} }


local_scheduler_t::~local_scheduler_t()
LIBRF_API local_scheduler_t::~local_scheduler_t()
{ {
if (th_scheduler_ptr == _scheduler_ptr) if (th_scheduler_ptr == _scheduler_ptr)
th_scheduler_ptr = nullptr; th_scheduler_ptr = nullptr;
delete _scheduler_ptr; delete _scheduler_ptr;
} }


scheduler_t::scheduler_t()
LIBRF_API scheduler_t::scheduler_t()
: _timer(std::make_shared<timer_manager>()) : _timer(std::make_shared<timer_manager>())
{ {
_runing_states.reserve(1024); _runing_states.reserve(1024);
th_scheduler_ptr = this; th_scheduler_ptr = this;
} }


scheduler_t::~scheduler_t()
LIBRF_API scheduler_t::~scheduler_t()
{ {
//cancel_all_task_(); //cancel_all_task_();
if (th_scheduler_ptr == this) if (th_scheduler_ptr == this)
th_scheduler_ptr = nullptr; th_scheduler_ptr = nullptr;
} }


task_t* scheduler_t::new_task(task_t * task)
LIBRF_API task_t* scheduler_t::new_task(task_t * task)
{ {
state_base_t* sptr = task->_state.get(); state_base_t* sptr = task->_state.get();
sptr->set_scheduler(this); sptr->set_scheduler(this);
return task; return task;
} }


std::unique_ptr<task_t> scheduler_t::del_switch(state_base_t* sptr)
LIBRF_API std::unique_ptr<task_t> scheduler_t::del_switch(state_base_t* sptr)
{ {
#if !RESUMEF_DISABLE_MULT_THREAD #if !RESUMEF_DISABLE_MULT_THREAD
scoped_lock<spinlock> __guard(_lock_ready); scoped_lock<spinlock> __guard(_lock_ready);
} }
*/ */


bool scheduler_t::run_one_batch()
LIBRF_API bool scheduler_t::run_one_batch()
{ {
this->_timer->update(); this->_timer->update();


return true; return true;
} }


void scheduler_t::run_until_notask()
LIBRF_API void scheduler_t::run_until_notask()
{ {
for(;;) for(;;)
{ {
}; };
} }


scheduler_t scheduler_t::g_scheduler;
LIBRF_API scheduler_t scheduler_t::g_scheduler;
} }

+ 1
- 1
source/sleep.cpp View File



namespace librf namespace librf
{ {
future_t<> sleep_until_(std::chrono::system_clock::time_point tp_, scheduler_t& scheduler_)
LIBRF_API future_t<> sleep_until_(std::chrono::system_clock::time_point tp_, scheduler_t& scheduler_)
{ {
awaitable_t<> awaitable; awaitable_t<> awaitable;



+ 16
- 16
source/state.cpp View File



namespace librf namespace librf
{ {
state_base_t::~state_base_t()
LIBRF_API state_base_t::~state_base_t()
{ {
} }
void state_base_t::destroy_deallocate()
LIBRF_API void state_base_t::destroy_deallocate()
{ {
delete this; delete this;
} }
state_base_t* state_base_t::get_parent() const noexcept
LIBRF_API state_base_t* state_base_t::get_parent() const noexcept
{ {
return nullptr; return nullptr;
} }


void state_future_t::destroy_deallocate()
LIBRF_API void state_future_t::destroy_deallocate()
{ {
size_t _Size = this->_alloc_size; size_t _Size = this->_alloc_size;
#if RESUMEF_DEBUG_COUNTER #if RESUMEF_DEBUG_COUNTER
return _Al.deallocate(reinterpret_cast<char*>(this), _Size); return _Al.deallocate(reinterpret_cast<char*>(this), _Size);
} }


state_generator_t* state_generator_t::_Alloc_state()
LIBRF_API state_generator_t* state_generator_t::_Alloc_state()
{ {
_Alloc_char _Al; _Alloc_char _Al;
size_t _Size = _Align_size<state_generator_t>(); size_t _Size = _Align_size<state_generator_t>();
return new(_Ptr) state_generator_t(); return new(_Ptr) state_generator_t();
} }


void state_generator_t::destroy_deallocate()
LIBRF_API void state_generator_t::destroy_deallocate()
{ {
size_t _Size = _Align_size<state_generator_t>(); size_t _Size = _Align_size<state_generator_t>();
#if RESUMEF_INLINE_STATE #if RESUMEF_INLINE_STATE
return _Al.deallocate(reinterpret_cast<char*>(this), _Size); return _Al.deallocate(reinterpret_cast<char*>(this), _Size);
} }


void state_generator_t::resume()
LIBRF_API void state_generator_t::resume()
{ {
if (likely(_coro)) if (likely(_coro))
{ {
} }
} }


bool state_generator_t::has_handler() const noexcept
LIBRF_API bool state_generator_t::has_handler() const noexcept
{ {
return (bool)_coro; return (bool)_coro;
} }
bool state_generator_t::switch_scheduler_await_suspend(scheduler_t* sch)
LIBRF_API bool state_generator_t::switch_scheduler_await_suspend(scheduler_t* sch)
{ {
assert(sch != nullptr); assert(sch != nullptr);


return true; return true;
} }


state_base_t* state_future_t::get_parent() const noexcept
LIBRF_API state_base_t* state_future_t::get_parent() const noexcept
{ {
return _parent; return _parent;
} }


void state_future_t::resume()
LIBRF_API void state_future_t::resume()
{ {
std::unique_lock<lock_type> __guard(_mtx); std::unique_lock<lock_type> __guard(_mtx);


} }
} }


bool state_future_t::has_handler() const noexcept
LIBRF_API bool state_future_t::has_handler() const noexcept
{ {
scoped_lock<lock_type> __guard(this->_mtx); scoped_lock<lock_type> __guard(this->_mtx);
return has_handler_skip_lock(); return has_handler_skip_lock();
} }


bool state_future_t::switch_scheduler_await_suspend(scheduler_t* sch)
LIBRF_API bool state_future_t::switch_scheduler_await_suspend(scheduler_t* sch)
{ {
assert(sch != nullptr); assert(sch != nullptr);
scoped_lock<lock_type> __guard(this->_mtx); scoped_lock<lock_type> __guard(this->_mtx);
return true; return true;
} }


void state_t<void>::future_await_resume()
LIBRF_API void state_t<void>::future_await_resume()
{ {
scoped_lock<lock_type> __guard(this->_mtx); scoped_lock<lock_type> __guard(this->_mtx);


std::rethrow_exception(std::make_exception_ptr(future_exception{error_code::not_ready})); std::rethrow_exception(std::make_exception_ptr(future_exception{error_code::not_ready}));
} }


void state_t<void>::set_value()
LIBRF_API void state_t<void>::set_value()
{ {
scoped_lock<lock_type> __guard(this->_mtx); scoped_lock<lock_type> __guard(this->_mtx);
this->_has_value.store(result_type::Value, std::memory_order_release); this->_has_value.store(result_type::Value, std::memory_order_release);
} }
} }


void state_t<void>::set_exception(std::exception_ptr e)
LIBRF_API void state_t<void>::set_exception(std::exception_ptr e)
{ {
scoped_lock<lock_type> __guard(this->_mtx); scoped_lock<lock_type> __guard(this->_mtx);
this->_exception = std::move(e); this->_exception = std::move(e);

+ 7
- 7
source/timer.cpp View File



namespace librf namespace librf
{ {
timer_manager::timer_manager()
LIBRF_API timer_manager::timer_manager()
{ {
_added_timers.reserve(128); _added_timers.reserve(128);
} }


timer_manager::~timer_manager()
LIBRF_API timer_manager::~timer_manager()
{ {
clear(); clear();
} }
void timer_manager::call_target_(const timer_target_ptr & sptr, bool canceld)
LIBRF_API void timer_manager::call_target_(const timer_target_ptr & sptr, bool canceld)
{ {
auto cb = std::move(sptr->cb); auto cb = std::move(sptr->cb);
sptr->st = timer_target::State::Invalid; sptr->st = timer_target::State::Invalid;
if(cb) cb(canceld); if(cb) cb(canceld);
} }


void timer_manager::clear()
LIBRF_API void timer_manager::clear()
{ {
#if !RESUMEF_DISABLE_MULT_THREAD #if !RESUMEF_DISABLE_MULT_THREAD
std::unique_lock<spinlock> __lock(_added_mtx); std::unique_lock<spinlock> __lock(_added_mtx);
call_target_(kv.second, true); call_target_(kv.second, true);
} }


detail::timer_target_ptr timer_manager::add_(const timer_target_ptr & sptr)
LIBRF_API detail::timer_target_ptr timer_manager::add_(const timer_target_ptr & sptr)
{ {
assert(sptr); assert(sptr);
assert(sptr->st == timer_target::State::Invalid); assert(sptr->st == timer_target::State::Invalid);
return sptr; return sptr;
} }


bool timer_manager::stop(const timer_target_ptr & sptr)
LIBRF_API bool timer_manager::stop(const timer_target_ptr & sptr)
{ {
if (!sptr || sptr->st == timer_target::State::Invalid) if (!sptr || sptr->st == timer_target::State::Invalid)
return false; return false;
return true; return true;
} }


void timer_manager::update()
LIBRF_API void timer_manager::update()
{ {
{ {
#if !RESUMEF_DISABLE_MULT_THREAD #if !RESUMEF_DISABLE_MULT_THREAD

+ 6
- 6
source/when_v2.cpp View File

{ {
namespace detail namespace detail
{ {
state_when_t::state_when_t(intptr_t counter_)
LIBRF_API state_when_t::state_when_t(intptr_t counter_)
:_counter(counter_) :_counter(counter_)
{ {
} }


void state_when_t::resume()
LIBRF_API void state_when_t::resume()
{ {
coroutine_handle<> handler = _coro; coroutine_handle<> handler = _coro;
if (handler) if (handler)
} }
} }


bool state_when_t::has_handler() const noexcept
LIBRF_API bool state_when_t::has_handler() const noexcept
{ {
return (bool)_coro; return (bool)_coro;
} }


void state_when_t::on_cancel() noexcept
LIBRF_API void state_when_t::on_cancel() noexcept
{ {
scoped_lock<lock_type> lock_(_lock); scoped_lock<lock_type> lock_(_lock);


this->_coro = nullptr; this->_coro = nullptr;
} }


bool state_when_t::on_notify_one()
LIBRF_API bool state_when_t::on_notify_one()
{ {
scoped_lock<lock_type> lock_(_lock); scoped_lock<lock_type> lock_(_lock);


return false; return false;
} }


bool state_when_t::on_timeout()
LIBRF_API bool state_when_t::on_timeout()
{ {
scoped_lock<lock_type> lock_(_lock); scoped_lock<lock_type> lock_(_lock);



Loading…
Cancel
Save