@@ -12,3 +12,5 @@ private | |||
bin | |||
out | |||
/CMakeSettings.json | |||
install | |||
lib |
@@ -54,7 +54,8 @@ option(OPT_DEBUG_COUNTER "Debug objects count" OFF) | |||
option(OPT_KEEP_REAL_SIZE "Keep real size in queue" OFF) | |||
option(OPT_DISABLE_MULT_THREAD "Disable multi-threaded scheduler" 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(OPT_USE_MIMALLOC) | |||
@@ -92,10 +93,6 @@ endif() | |||
if(OPT_DISABLE_MULT_THREAD) | |||
set(RESUMEF_DISABLE_MULT_THREAD 1) | |||
endif() | |||
if(OPT_DYNAMIC_LIBRARY) | |||
set(RESUMEF_USE_SHARD_LIBRARY 1) | |||
add_compile_definitions("-DRESUMEF_DYNAMIC_EXPORTS=1") | |||
endif() | |||
configure_file( | |||
${CMAKE_SOURCE_DIR}/config.h.in | |||
@@ -107,6 +104,7 @@ file(GLOB_RECURSE HEADER_FILES ${CMAKE_SOURCE_DIR}/include/*.*) | |||
file(GLOB_RECURSE SOURCE_FILES ${CMAKE_SOURCE_DIR}/source/*.*) | |||
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) | |||
if(OPT_DYNAMIC_LIBRARY) | |||
@@ -114,28 +112,39 @@ if(OPT_DYNAMIC_LIBRARY) | |||
${HEADER_FILES} | |||
${SOURCE_FILES} | |||
) | |||
target_compile_definitions(${PROJECT_NAME} | |||
PRIVATE LIBRF_DYNAMIC_EXPORTS=1 | |||
) | |||
else() | |||
add_library(${PROJECT_NAME} STATIC | |||
${HEADER_FILES} | |||
${SOURCE_FILES} | |||
) | |||
target_compile_definitions(${PROJECT_NAME} | |||
PRIVATE LIBRF_USE_STATIC_LIBRARY=1 | |||
) | |||
endif() | |||
target_include_directories(${PROJECT_NAME} | |||
PUBLIC | |||
${CMAKE_CURRENT_SOURCE_DIR}/include | |||
) | |||
include_directories( | |||
${CMAKE_SOURCE_DIR}/modern_cb | |||
) | |||
if(OPT_USE_MIMALLOC) | |||
set(LIB_MIMALLOC, "mimalloc") | |||
else() | |||
set(LIB_MIMALLOC, "") | |||
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) |
@@ -0,0 +1,2 @@ | |||
include(${CMAKE_CURRENT_LIST_DIR}/SelectDynamicLibrary.cmake) | |||
select_dynamic_library(librf librf/librf.h) |
@@ -0,0 +1,161 @@ | |||
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) |
@@ -0,0 +1,45 @@ | |||
| |||
# 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) |
@@ -71,6 +71,7 @@ extern "C" void _coro_resume_block(); | |||
#include "src/def.h" | |||
#include "src/macro_def.inl" | |||
#include "src/exception.inl" | |||
#include "src/counted_ptr.h" | |||
#include "src/type_traits.inl" | |||
#include "src/type_concept.inl" |
@@ -53,12 +53,6 @@ namespace librf | |||
* @brief 版本号。 | |||
*/ | |||
constexpr size_t _Version = LIB_RESUMEF_VERSION; | |||
/** | |||
* @brief 获得当前线程下的调度器。 | |||
*/ | |||
scheduler_t* this_scheduler(); | |||
} | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
@@ -102,6 +96,4 @@ namespace librf | |||
} | |||
} | |||
#include "exception.inl" | |||
#endif //DOXYGEN_SKIP_PROPERTY |
@@ -23,18 +23,18 @@ namespace librf | |||
* @brief 构造一个事件。 | |||
* @param initially 初始是否触发一次信号。 | |||
*/ | |||
event_t(bool initially = false); | |||
LIBRF_API event_t(bool initially = false); | |||
/** | |||
* @brief 构造一个无效的事件。 | |||
* @details 如果用于后续保存另外一个事件,则应当使用此构造函数,便于节省一次不必要的内部初始化。 | |||
*/ | |||
event_t(std::adopt_lock_t); | |||
LIBRF_API event_t(std::adopt_lock_t); | |||
/** | |||
* @brief 采用shared_ptr<>来保存内部的事件实现。故不必担心正在被等待的协程,因为事件提前销毁而出现异常。 | |||
*/ | |||
~event_t(); | |||
LIBRF_API ~event_t(); | |||
/** | |||
* @brief 向所有正在等待的协程触发一次信号。 |
@@ -8,8 +8,8 @@ namespace librf | |||
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 | |||
{ | |||
@@ -19,8 +19,8 @@ namespace librf | |||
{ | |||
_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: | |||
static constexpr bool USE_SPINLOCK = true; | |||
@@ -62,8 +62,8 @@ namespace librf | |||
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 bool on_notify(event_v2_impl* eptr) = 0; | |||
@@ -103,9 +103,9 @@ namespace librf | |||
: _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: | |||
//_value引用awaitor保存的值,这样可以尽可能减少创建state的可能。而不必进入没有state就没有value实体被用于返回。 | |||
//在调用on_notify()或on_timeout()任意之一后,置为nullptr。 | |||
@@ -121,9 +121,9 @@ namespace librf | |||
, _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; | |||
protected: |
@@ -23,12 +23,11 @@ namespace librf | |||
/** | |||
* @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<>时产生的异常。 | |||
*/ | |||
const char* get_error_string(error_code fe, const char* classname); | |||
struct future_exception : std::logic_error | |||
{ | |||
error_code _error; |
@@ -32,9 +32,9 @@ | |||
#endif // unlikely | |||
#endif // defined(__clang__) || defined(__GNUC__) | |||
#ifdef RESUMEF_USE_SHARD_LIBRARY | |||
#ifndef LIBRF_USE_STATIC_LIBRARY | |||
# if _WIN32 | |||
# ifdef RESUMEF_DYNAMIC_EXPORTS | |||
# ifdef LIBRF_DYNAMIC_EXPORTS | |||
# define LIBRF_API __declspec(dllexport) | |||
# else //RESUMEF_DYNAMIC_EXPORTS | |||
# define LIBRF_API __declspec(dllimport) |
@@ -209,13 +209,13 @@ namespace librf | |||
> | |||
static void unlock(void* unique_address, _Mtxs&... mtxs); | |||
mutex_t(); | |||
LIBRF_API 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(mutex_t&&) = default; |
@@ -10,15 +10,15 @@ namespace librf | |||
: _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 | |||
{ | |||
@@ -44,10 +44,10 @@ namespace librf | |||
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: | |||
static constexpr bool USE_SPINLOCK = true; | |||
@@ -55,8 +55,8 @@ namespace librf | |||
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); //内部不加锁,加锁由外部来进行 | |||
LIBRF_API bool try_lock_lockless(void* sch) noexcept; //内部不加锁,加锁由外部来进行 | |||
LIBRF_API void add_wait_list_lockless(state_mutex_t* state); //内部不加锁,加锁由外部来进行 | |||
lock_type _lock; //保证访问本对象是线程安全的 | |||
private: |
@@ -16,14 +16,14 @@ namespace librf | |||
*/ | |||
struct task_t | |||
{ | |||
task_t() noexcept; | |||
virtual ~task_t(); | |||
LIBRF_API task_t() noexcept; | |||
LIBRF_API virtual ~task_t(); | |||
/** | |||
* @brief 获取stop_source,第一次获取时,会生成一个有效的stop_source。 | |||
* @return stop_source | |||
*/ | |||
const stop_source & get_stop_source(); | |||
LIBRF_API const stop_source & get_stop_source(); | |||
/** | |||
* @brief 获取一个跟stop_source绑定的,新的stop_token。 |
@@ -2,6 +2,11 @@ | |||
namespace librf | |||
{ | |||
/** | |||
* @brief 获得当前线程下的调度器。 | |||
*/ | |||
LIBRF_API scheduler_t* this_scheduler(); | |||
/** | |||
* @brief 协程调度器。 | |||
* @details librf的设计原则之一,就是要将协程绑定在固定的调度器里执行。 | |||
@@ -28,7 +33,7 @@ namespace librf | |||
timer_mgr_ptr _timer; | |||
task_t* new_task(task_t* task); | |||
LIBRF_API task_t* new_task(task_t* task); | |||
//void cancel_all_task_(); | |||
public: | |||
/** | |||
@@ -36,13 +41,13 @@ namespace librf | |||
* @details 这是协程调度器提供的主要接口。同一个调度器非线程安全,不可重入。\n | |||
* 调用者要保证此函数始终在同一个线程里调用。 | |||
*/ | |||
bool run_one_batch(); | |||
LIBRF_API bool run_one_batch(); | |||
/** | |||
* @brief 循环运行所有的协程,直到所有协程都运行完成。 | |||
* @details 通常用于测试代码。 | |||
*/ | |||
void run_until_notask(); | |||
LIBRF_API void run_until_notask(); | |||
//void break_all(); | |||
@@ -88,24 +93,24 @@ namespace librf | |||
} | |||
#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; | |||
protected: | |||
scheduler_t(); | |||
LIBRF_API scheduler_t(); | |||
public: | |||
~scheduler_t(); | |||
LIBRF_API ~scheduler_t(); | |||
scheduler_t(scheduler_t&& right_) = delete; | |||
scheduler_t& operator = (scheduler_t&& right_) = delete; | |||
scheduler_t(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 | |||
}; | |||
@@ -121,17 +126,17 @@ namespace librf | |||
/** | |||
* @brief 尽可能的创建一个线程相关的调度器。 | |||
*/ | |||
local_scheduler_t(); | |||
LIBRF_API local_scheduler_t(); | |||
/** | |||
* @brief 将指定的调度器绑定到当前线程上。 | |||
*/ | |||
local_scheduler_t(scheduler_t & sch) noexcept; | |||
LIBRF_API local_scheduler_t(scheduler_t & sch) noexcept; | |||
/** | |||
* @brief 如果当前线程绑定的调度器由local_scheduler_t所创建,则会销毁调度器,并解绑线程。 | |||
*/ | |||
~local_scheduler_t(); | |||
LIBRF_API ~local_scheduler_t(); | |||
local_scheduler_t(local_scheduler_t&& right_) = delete; | |||
local_scheduler_t& operator = (local_scheduler_t&& right_) = delete; |
@@ -14,7 +14,7 @@ namespace librf | |||
* @return [co_await] void | |||
* @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 协程专用的睡眠功能。 |
@@ -30,13 +30,13 @@ namespace librf | |||
// 二、没有co_await操作,直接加入到了调度器里,则_coro在初始时为nullptr。调度器需要特殊处理此种情况。 | |||
coroutine_handle<> _coro; | |||
virtual ~state_base_t(); | |||
LIBRF_API virtual ~state_base_t(); | |||
private: | |||
virtual void destroy_deallocate(); | |||
LIBRF_API virtual void destroy_deallocate(); | |||
public: | |||
virtual void resume() = 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 | |||
{ | |||
@@ -70,13 +70,13 @@ namespace librf | |||
struct state_generator_t : public state_base_t | |||
{ | |||
private: | |||
virtual void destroy_deallocate() override; | |||
LIBRF_API virtual void destroy_deallocate() override; | |||
state_generator_t() = default; | |||
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 | |||
{ | |||
@@ -89,7 +89,7 @@ namespace librf | |||
return new(_Ptr) state_generator_t(); | |||
} | |||
#endif | |||
static state_generator_t* _Alloc_state(); | |||
LIBRF_API static state_generator_t* _Alloc_state(); | |||
}; | |||
/** | |||
@@ -139,10 +139,10 @@ namespace librf | |||
_is_future = !awaitor; | |||
} | |||
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 | |||
{ | |||
@@ -177,7 +177,7 @@ namespace librf | |||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||
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>>> | |||
void promise_initial_suspend(coroutine_handle<_PromiseT> handler); | |||
@@ -312,12 +312,12 @@ namespace librf | |||
private: | |||
explicit state_t(bool awaitor) noexcept :state_future_t(awaitor) {} | |||
public: | |||
void future_await_resume(); | |||
LIBRF_API void future_await_resume(); | |||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | |||
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> | |||
inline void throw_exception(_Exp e) |
@@ -94,8 +94,8 @@ namespace librf | |||
typedef std::multimap<clock_type::time_point, timer_target_ptr> timer_map_type; | |||
#endif | |||
public: | |||
timer_manager(); | |||
~timer_manager(); | |||
LIBRF_API timer_manager(); | |||
LIBRF_API ~timer_manager(); | |||
template<class _Rep, class _Period, class _Cb> | |||
timer_target_ptr add(const std::chrono::duration<_Rep, _Period> & dt_, _Cb && cb_) | |||
@@ -118,14 +118,14 @@ namespace librf | |||
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 | |||
{ | |||
return _runing_timers.empty() && _added_timers.empty(); | |||
} | |||
void clear(); | |||
void update(); | |||
LIBRF_API void clear(); | |||
LIBRF_API void update(); | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
template<class _Cb> | |||
@@ -145,8 +145,8 @@ namespace librf | |||
timer_vector_type _added_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 | |||
}; | |||
@@ -22,14 +22,14 @@ namespace librf | |||
{ | |||
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>>> |
@@ -4,7 +4,7 @@ namespace librf | |||
{ | |||
namespace detail | |||
{ | |||
void state_event_base_t::resume() | |||
LIBRF_API void state_event_base_t::resume() | |||
{ | |||
coroutine_handle<> handler = _coro; | |||
if (handler) | |||
@@ -15,12 +15,12 @@ namespace librf | |||
} | |||
} | |||
bool state_event_base_t::has_handler() const noexcept | |||
LIBRF_API bool state_event_base_t::has_handler() const noexcept | |||
{ | |||
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); | |||
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) | |||
@@ -32,7 +32,7 @@ namespace librf | |||
} | |||
} | |||
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); | |||
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) | |||
@@ -49,7 +49,7 @@ namespace librf | |||
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); | |||
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) | |||
@@ -69,7 +69,7 @@ namespace librf | |||
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); | |||
if (oldValue >= 0 && _counter.compare_exchange_strong(oldValue, -1, std::memory_order_acq_rel)) | |||
@@ -81,7 +81,7 @@ namespace librf | |||
} | |||
} | |||
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); | |||
if (oldValue <= 0) return false; | |||
@@ -102,7 +102,7 @@ namespace librf | |||
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); | |||
if (oldValue >= 0 && _counter.compare_exchange_strong(oldValue, -1, std::memory_order_acq_rel)) | |||
@@ -121,7 +121,7 @@ namespace librf | |||
event_v2_impl::event_v2_impl(bool initially) noexcept | |||
LIBRF_API event_v2_impl::event_v2_impl(bool initially) noexcept | |||
: _counter(initially ? 1 : 0) | |||
{ | |||
} | |||
@@ -153,12 +153,12 @@ namespace librf | |||
list.clear(); | |||
} | |||
event_v2_impl::~event_v2_impl() | |||
LIBRF_API event_v2_impl::~event_v2_impl() | |||
{ | |||
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); | |||
@@ -171,7 +171,7 @@ namespace librf | |||
} | |||
} | |||
void event_v2_impl::signal() noexcept | |||
LIBRF_API void event_v2_impl::signal() noexcept | |||
{ | |||
scoped_lock<lock_type> lock_(_lock); | |||
@@ -186,16 +186,16 @@ namespace librf | |||
} | |||
} | |||
event_t::event_t(bool initially) | |||
LIBRF_API event_t::event_t(bool 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() | |||
{ | |||
} | |||
} |
@@ -4,7 +4,7 @@ namespace librf | |||
{ | |||
namespace detail | |||
{ | |||
void state_mutex_t::resume() | |||
LIBRF_API void state_mutex_t::resume() | |||
{ | |||
coroutine_handle<> handler = _coro; | |||
if (handler) | |||
@@ -15,18 +15,18 @@ namespace librf | |||
} | |||
} | |||
bool state_mutex_t::has_handler() const noexcept | |||
LIBRF_API bool state_mutex_t::has_handler() const noexcept | |||
{ | |||
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; | |||
} | |||
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); | |||
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) | |||
@@ -38,7 +38,7 @@ namespace librf | |||
} | |||
} | |||
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); | |||
@@ -57,7 +57,7 @@ namespace librf | |||
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); | |||
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) | |||
@@ -74,7 +74,7 @@ namespace librf | |||
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, | |||
[st = counted_ptr<state_mutex_t>{ this }](bool canceld) | |||
@@ -86,7 +86,7 @@ namespace librf | |||
void mutex_v2_impl::lock_until_succeed(void* sch) | |||
LIBRF_API void mutex_v2_impl::lock_until_succeed(void* sch) | |||
{ | |||
assert(sch != nullptr); | |||
@@ -98,7 +98,7 @@ namespace librf | |||
} | |||
} | |||
bool mutex_v2_impl::try_lock(void* sch) | |||
LIBRF_API bool mutex_v2_impl::try_lock(void* sch) | |||
{ | |||
assert(sch != nullptr); | |||
@@ -106,7 +106,7 @@ namespace librf | |||
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); | |||
@@ -119,7 +119,7 @@ namespace librf | |||
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); | |||
@@ -138,7 +138,7 @@ namespace librf | |||
return false; | |||
} | |||
bool mutex_v2_impl::unlock(void* sch) | |||
LIBRF_API bool mutex_v2_impl::unlock(void* sch) | |||
{ | |||
assert(sch != nullptr); | |||
@@ -175,7 +175,7 @@ namespace librf | |||
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); | |||
@@ -183,16 +183,16 @@ namespace librf | |||
} | |||
} | |||
mutex_t::mutex_t() | |||
LIBRF_API mutex_t::mutex_t() | |||
: _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 | |||
{ | |||
} | |||
} |
@@ -2,16 +2,16 @@ | |||
namespace librf | |||
{ | |||
task_t::task_t() noexcept | |||
LIBRF_API task_t::task_t() noexcept | |||
: _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(); | |||
return _stop; |
@@ -24,7 +24,7 @@ namespace librf | |||
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) | |||
{ | |||
@@ -40,12 +40,12 @@ namespace librf | |||
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; | |||
} | |||
local_scheduler_t::local_scheduler_t() | |||
LIBRF_API local_scheduler_t::local_scheduler_t() | |||
{ | |||
if (th_scheduler_ptr == nullptr) | |||
{ | |||
@@ -58,7 +58,7 @@ namespace librf | |||
} | |||
} | |||
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) | |||
{ | |||
@@ -68,14 +68,14 @@ namespace librf | |||
_scheduler_ptr = nullptr; | |||
} | |||
local_scheduler_t::~local_scheduler_t() | |||
LIBRF_API local_scheduler_t::~local_scheduler_t() | |||
{ | |||
if (th_scheduler_ptr == _scheduler_ptr) | |||
th_scheduler_ptr = nullptr; | |||
delete _scheduler_ptr; | |||
} | |||
scheduler_t::scheduler_t() | |||
LIBRF_API scheduler_t::scheduler_t() | |||
: _timer(std::make_shared<timer_manager>()) | |||
{ | |||
_runing_states.reserve(1024); | |||
@@ -85,14 +85,14 @@ namespace librf | |||
th_scheduler_ptr = this; | |||
} | |||
scheduler_t::~scheduler_t() | |||
LIBRF_API scheduler_t::~scheduler_t() | |||
{ | |||
//cancel_all_task_(); | |||
if (th_scheduler_ptr == this) | |||
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(); | |||
sptr->set_scheduler(this); | |||
@@ -113,7 +113,7 @@ namespace librf | |||
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 | |||
scoped_lock<spinlock> __guard(_lock_ready); | |||
@@ -147,7 +147,7 @@ namespace librf | |||
} | |||
*/ | |||
bool scheduler_t::run_one_batch() | |||
LIBRF_API bool scheduler_t::run_one_batch() | |||
{ | |||
this->_timer->update(); | |||
@@ -168,7 +168,7 @@ namespace librf | |||
return true; | |||
} | |||
void scheduler_t::run_until_notask() | |||
LIBRF_API void scheduler_t::run_until_notask() | |||
{ | |||
for(;;) | |||
{ | |||
@@ -189,5 +189,5 @@ namespace librf | |||
}; | |||
} | |||
scheduler_t scheduler_t::g_scheduler; | |||
LIBRF_API scheduler_t scheduler_t::g_scheduler; | |||
} |
@@ -2,7 +2,7 @@ | |||
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; | |||
@@ -2,21 +2,21 @@ | |||
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; | |||
} | |||
state_base_t* state_base_t::get_parent() const noexcept | |||
LIBRF_API state_base_t* state_base_t::get_parent() const noexcept | |||
{ | |||
return nullptr; | |||
} | |||
void state_future_t::destroy_deallocate() | |||
LIBRF_API void state_future_t::destroy_deallocate() | |||
{ | |||
size_t _Size = this->_alloc_size; | |||
#if RESUMEF_DEBUG_COUNTER | |||
@@ -28,7 +28,7 @@ namespace librf | |||
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; | |||
size_t _Size = _Align_size<state_generator_t>(); | |||
@@ -39,7 +39,7 @@ namespace librf | |||
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>(); | |||
#if RESUMEF_INLINE_STATE | |||
@@ -55,7 +55,7 @@ namespace librf | |||
return _Al.deallocate(reinterpret_cast<char*>(this), _Size); | |||
} | |||
void state_generator_t::resume() | |||
LIBRF_API void state_generator_t::resume() | |||
{ | |||
if (likely(_coro)) | |||
{ | |||
@@ -75,12 +75,12 @@ namespace librf | |||
} | |||
} | |||
bool state_generator_t::has_handler() const noexcept | |||
LIBRF_API bool state_generator_t::has_handler() const noexcept | |||
{ | |||
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); | |||
@@ -102,12 +102,12 @@ namespace librf | |||
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; | |||
} | |||
void state_future_t::resume() | |||
LIBRF_API void state_future_t::resume() | |||
{ | |||
std::unique_lock<lock_type> __guard(_mtx); | |||
@@ -146,13 +146,13 @@ namespace librf | |||
} | |||
} | |||
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); | |||
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); | |||
scoped_lock<lock_type> __guard(this->_mtx); | |||
@@ -178,7 +178,7 @@ namespace librf | |||
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); | |||
@@ -188,7 +188,7 @@ namespace librf | |||
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); | |||
this->_has_value.store(result_type::Value, std::memory_order_release); | |||
@@ -203,7 +203,7 @@ namespace librf | |||
} | |||
} | |||
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); | |||
this->_exception = std::move(e); |
@@ -2,17 +2,17 @@ | |||
namespace librf | |||
{ | |||
timer_manager::timer_manager() | |||
LIBRF_API timer_manager::timer_manager() | |||
{ | |||
_added_timers.reserve(128); | |||
} | |||
timer_manager::~timer_manager() | |||
LIBRF_API timer_manager::~timer_manager() | |||
{ | |||
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); | |||
sptr->st = timer_target::State::Invalid; | |||
@@ -23,7 +23,7 @@ namespace librf | |||
if(cb) cb(canceld); | |||
} | |||
void timer_manager::clear() | |||
LIBRF_API void timer_manager::clear() | |||
{ | |||
#if !RESUMEF_DISABLE_MULT_THREAD | |||
std::unique_lock<spinlock> __lock(_added_mtx); | |||
@@ -41,7 +41,7 @@ namespace librf | |||
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->st == timer_target::State::Invalid); | |||
@@ -60,7 +60,7 @@ namespace librf | |||
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) | |||
return false; | |||
@@ -72,7 +72,7 @@ namespace librf | |||
return true; | |||
} | |||
void timer_manager::update() | |||
LIBRF_API void timer_manager::update() | |||
{ | |||
{ | |||
#if !RESUMEF_DISABLE_MULT_THREAD |
@@ -4,12 +4,12 @@ namespace librf | |||
{ | |||
namespace detail | |||
{ | |||
state_when_t::state_when_t(intptr_t counter_) | |||
LIBRF_API state_when_t::state_when_t(intptr_t counter_) | |||
:_counter(counter_) | |||
{ | |||
} | |||
void state_when_t::resume() | |||
LIBRF_API void state_when_t::resume() | |||
{ | |||
coroutine_handle<> handler = _coro; | |||
if (handler) | |||
@@ -20,12 +20,12 @@ namespace librf | |||
} | |||
} | |||
bool state_when_t::has_handler() const noexcept | |||
LIBRF_API bool state_when_t::has_handler() const noexcept | |||
{ | |||
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); | |||
@@ -33,7 +33,7 @@ namespace librf | |||
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); | |||
@@ -48,7 +48,7 @@ namespace librf | |||
return false; | |||
} | |||
bool state_when_t::on_timeout() | |||
LIBRF_API bool state_when_t::on_timeout() | |||
{ | |||
scoped_lock<lock_type> lock_(_lock); | |||