Merge branch 'master' of code.uocat.com:tqcq/sled

This commit is contained in:
tqcq 2024-03-21 08:20:07 +08:00
commit 00cfa439ae
14 changed files with 198 additions and 165 deletions

View File

@ -864,6 +864,7 @@ if(GPERFTOOLS_BUILD_HEAP_CHECKER OR GPERFTOOLS_BUILD_HEAP_PROFILER)
add_library(tcmalloc_internal INTERFACE) add_library(tcmalloc_internal INTERFACE)
target_sources(tcmalloc_internal INTERFACE $<TARGET_OBJECTS:tcmalloc_internal_object>) target_sources(tcmalloc_internal INTERFACE $<TARGET_OBJECTS:tcmalloc_internal_object>)
target_link_libraries(tcmalloc_internal INTERFACE ${libtcmalloc_internal_la_LIBADD}) target_link_libraries(tcmalloc_internal INTERFACE ${libtcmalloc_internal_la_LIBADD})
target_include_directories(tcmalloc_internal INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src)
add_library(tcmalloc SHARED ${libtcmalloc_la_SOURCES}) add_library(tcmalloc SHARED ${libtcmalloc_la_SOURCES})
target_compile_definitions(tcmalloc PRIVATE ${libtcmalloc_la_DEFINE}) target_compile_definitions(tcmalloc PRIVATE ${libtcmalloc_la_DEFINE})
@ -939,6 +940,7 @@ if(GPERFTOOLS_BUILD_CPU_PROFILER)
add_library(profiler SHARED ${libprofiler_la_SOURCES}) add_library(profiler SHARED ${libprofiler_la_SOURCES})
target_link_libraries(profiler PRIVATE ${libprofiler_la_LIBADD}) target_link_libraries(profiler PRIVATE ${libprofiler_la_LIBADD})
target_link_libraries(profiler PRIVATE Threads::Threads) target_link_libraries(profiler PRIVATE Threads::Threads)
target_include_directories(profiler INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src)
set_target_properties(profiler PROPERTIES set_target_properties(profiler PROPERTIES
VERSION ${PROFILER_SO_VERSION} VERSION ${PROFILER_SO_VERSION}
SOVERSION ${PROFILER_SO_VERSION}) SOVERSION ${PROFILER_SO_VERSION})
@ -946,6 +948,7 @@ if(GPERFTOOLS_BUILD_CPU_PROFILER)
if(GPERFTOOLS_BUILD_STATIC) if(GPERFTOOLS_BUILD_STATIC)
add_library(profiler_static STATIC ${libprofiler_la_SOURCES}) add_library(profiler_static STATIC ${libprofiler_la_SOURCES})
target_link_libraries(profiler_static PRIVATE ${libprofiler_la_LIBADD}) target_link_libraries(profiler_static PRIVATE ${libprofiler_la_LIBADD})
target_include_directories(profiler_static INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src)
if(NOT MSVC) if(NOT MSVC)
set_target_properties(profiler_static PROPERTIES OUTPUT_NAME profiler) set_target_properties(profiler_static PROPERTIES OUTPUT_NAME profiler)
endif() endif()
@ -987,6 +990,7 @@ if(GPERFTOOLS_BUILD_HEAP_PROFILER OR GPERFTOOLS_BUILD_HEAP_CHECKER)
add_library(tcmalloc_and_profiler_static STATIC ${libtcmalloc_la_SOURCES} ${libprofiler_la_SOURCES}) add_library(tcmalloc_and_profiler_static STATIC ${libtcmalloc_la_SOURCES} ${libprofiler_la_SOURCES})
target_compile_definitions(tcmalloc_and_profiler_static PRIVATE ${libtcmalloc_la_DEFINE}) target_compile_definitions(tcmalloc_and_profiler_static PRIVATE ${libtcmalloc_la_DEFINE})
target_link_libraries(tcmalloc_and_profiler_static PRIVATE ${libtcmalloc_la_LIBADD}) target_link_libraries(tcmalloc_and_profiler_static PRIVATE ${libtcmalloc_la_LIBADD})
target_include_directories(tcmalloc_and_profiler_static INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src)
if(NOT MSVC) if(NOT MSVC)
set_target_properties(tcmalloc_and_profiler_static PROPERTIES set_target_properties(tcmalloc_and_profiler_static PROPERTIES
OUTPUT_NAME tcmalloc_and_profiler) OUTPUT_NAME tcmalloc_and_profiler)

View File

@ -69,7 +69,7 @@ option(protobuf_BUILD_SHARED_LIBS "Build Shared Libraries" ${protobuf_BUILD_SHAR
include(CMakeDependentOption) include(CMakeDependentOption)
cmake_dependent_option(protobuf_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON cmake_dependent_option(protobuf_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON
"NOT protobuf_BUILD_SHARED_LIBS" OFF) "NOT protobuf_BUILD_SHARED_LIBS" OFF)
set(protobuf_WITH_ZLIB_DEFAULT ON) set(protobuf_WITH_ZLIB_DEFAULT OFF)
option(protobuf_WITH_ZLIB "Build with zlib support" ${protobuf_WITH_ZLIB_DEFAULT}) option(protobuf_WITH_ZLIB "Build with zlib support" ${protobuf_WITH_ZLIB_DEFAULT})
set(protobuf_DEBUG_POSTFIX "d" set(protobuf_DEBUG_POSTFIX "d"
CACHE STRING "Default debug postfix") CACHE STRING "Default debug postfix")

View File

@ -16,7 +16,7 @@ set(BUILD_EXAMPLES OFF)
add_library(sled STATIC "") add_library(sled STATIC "")
add_subdirectory(3party/gperftools EXCLUDE_FROM_ALL) add_subdirectory(3party/gperftools EXCLUDE_FROM_ALL)
add_subdirectory(3party/cppuprofile EXCLUDE_FROM_ALL) # add_subdirectory(3party/cppuprofile EXCLUDE_FROM_ALL)
add_subdirectory(3party/protobuf-3.21.12 EXCLUDE_FROM_ALL) add_subdirectory(3party/protobuf-3.21.12 EXCLUDE_FROM_ALL)
if (NOT TARGET marl) if (NOT TARGET marl)
add_subdirectory(3party/marl EXCLUDE_FROM_ALL) add_subdirectory(3party/marl EXCLUDE_FROM_ALL)
@ -74,11 +74,24 @@ target_sources(
# set(BUILD_RTTR_DYNAMIC OFF) set(BUILD_UNIT_TESTS OFF) # set(BUILD_RTTR_DYNAMIC OFF) set(BUILD_UNIT_TESTS OFF)
# set(BUILD_WITH_STATIC_RUNTIME_LIBS ON) set(BUILD_WITH_DOCUMENTATION OFF) # set(BUILD_WITH_STATIC_RUNTIME_LIBS ON) set(BUILD_WITH_DOCUMENTATION OFF)
# add_subdirectory(3party/rttr EXCLUDE_FROM_ALL) # add_subdirectory(3party/rttr EXCLUDE_FROM_ALL)
include(CheckCCompilerFlag)
check_c_compiler_flag("-Wl,--whole-archive" SUPPORT_COMPILE_WHOLE_ARCHIVE)
if (SUPPORT_COMPILE_WHOLE_ARCHIVE)
set(WHOLE_ARCHIVE_WRAPPER_START "-Wl,--whole-archive")
set(WHOLE_ARCHIVE_WRAPPER_END "-Wl,--no-whole-archive")
endif()
target_link_libraries(sled target_link_libraries(sled
PUBLIC rpc_core fmt marl protobuf::libprotobuf cppuprofile tcmalloc_and_profiler_static PUBLIC rpc_core fmt marl protobuf::libprotobuf # cppuprofile
# ${WHOLE_ARCHIVE_WRAPPER_START}
tcmalloc_and_profiler_static
# ${WHOLE_ARCHIVE_WRAPPER_END}
) )
## set fPIC
set_target_properties(sled PROPERTIES POSITION_INDEPENDENT_CODE ON)
if(SLED_BUILD_BENCHMARK) if(SLED_BUILD_BENCHMARK)
if (NOT TARGET benchmark) if (NOT TARGET benchmark)
find_package(benchmark REQUIRED) find_package(benchmark REQUIRED)

View File

@ -23,20 +23,18 @@ WasDeduced()
} }
}// namespace internal }// namespace internal
template<typename Arg = internal::Tag, template<typename Arg = internal::Tag, typename Callback = std::function<void()>>
typename Callback = std::function<void()>>
class Cleanup final { class Cleanup final {
public: public:
static_assert(internal::WasDeduced<Arg>(), static_assert(internal::WasDeduced<Arg>(), "Do not specify the first template argument");
"Do not specify the first template argument");
Cleanup(Callback callback) : callback_(std::move(callback)) {} Cleanup(Callback callback) : callback_(std::move(callback)) {}
Cleanup(Cleanup &&other) = default; Cleanup(Cleanup &&other) = default;
void Cancel() && { callback_.reset(); } void Cancel() { callback_.reset(); }
void Invoke() && void Invoke()
{ {
assert(callback_); assert(callback_);
(*callback_)(); (*callback_)();

View File

@ -2,7 +2,10 @@
#ifndef SLED_LANG_ATTRIBUTES_H #ifndef SLED_LANG_ATTRIBUTES_H
#define SLED_LANG_ATTRIBUTES_H #define SLED_LANG_ATTRIBUTES_H
#include <marl/tsa.h>
#define SLED_DEPRECATED() __attribute__((deprecated)) #define SLED_DEPRECATED() __attribute__((deprecated))
#ifndef THREAD_ANNOTATION_ATTRIBUTE__
#if defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__) && !defined(SWIG) #if defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__) && !defined(SWIG)
#define THREAD_ANNOTATION_ATTRIBUTE__(x) #define THREAD_ANNOTATION_ATTRIBUTE__(x)
#elif defined(__clang__) #elif defined(__clang__)
@ -10,12 +13,11 @@
#else #else
#define THREAD_ANNOTATION_ATTRIBUTE__(x) #define THREAD_ANNOTATION_ATTRIBUTE__(x)
#endif #endif
#endif// THREAD_ANNOTATION_ATTRIBUTE__
#if defined(GUARDED_BY) #ifndef GUARDED_BY
#undef GUARDED_BY
#endif
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) #define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#endif
#if defined(__clang__) #if defined(__clang__)
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__)) #define EXCLUSIVE_TRYLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
@ -24,14 +26,14 @@
#define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__)) #define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) // #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#else// defined(__clang__) #else// defined(__clang__)
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock(__VA_ARGS__)) #define EXCLUSIVE_TRYLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock(__VA_ARGS__))
#define EXCLUSIVE_LOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock(__VA_ARGS__)) #define EXCLUSIVE_LOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock(__VA_ARGS__))
#define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock(__VA_ARGS__)) #define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock(__VA_ARGS__))
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x)) // #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x))
#endif #endif
#endif// SLED_LANG_ATTRIBUTES_H #endif// SLED_LANG_ATTRIBUTES_H

View File

@ -13,92 +13,97 @@
namespace sled { namespace sled {
enum class LogLevel { enum class LogLevel {
kTrace, kTrace = 0,
kDebug, kDebug = 1,
kInfo, kInfo = 2,
kWarning, kWarning = 3,
kError, kError = 4,
kFatal, kFatal = 5,
}; };
void SetLogLevel(LogLevel level); void SetLogLevel(LogLevel level);
void Log(LogLevel level, void Log(LogLevel level, const char *tag, const char *fmt, const char *file_name, int line, const char *func_name, ...);
const char *tag,
const char *fmt,
const char *file_name,
int line,
const char *func_name,
...);
}// namespace sled }// namespace sled
// #define _SLOG(level, tag, ...) \ // #define _SLOG(level, tag, ...) \
// sled::Log(level, tag, fmt, __FILE__, __FUNCTION__, __VA_ARGS__) // sled::Log(level, tag, fmt, __FILE__, __FUNCTION__, __VA_ARGS__)
#define _SLOG(level, tag, fmt_str, ...) \ #define _SLOG(level, tag, fmt_str, ...) \
do { \ do { \
std::string __fmt_str; \ std::string __fmt_str; \
try { \ try { \
__fmt_str = fmt::format(fmt_str, ##__VA_ARGS__); \ __fmt_str = fmt::format(fmt_str, ##__VA_ARGS__); \
} catch (const std::exception &e) { \ } catch (const std::exception &e) { \
__fmt_str = " fmt error: " + std::string(e.what()); \ __fmt_str = " fmt error: " + std::string(e.what()); \
} \ } \
sled::Log(level, tag, __fmt_str.c_str(), __FILE__, __LINE__, \ sled::Log(level, tag, __fmt_str.c_str(), __FILE__, __LINE__, __FUNCTION__); \
__FUNCTION__); \
} while (0) } while (0)
#define SLOG(level, tag, fmt, ...) _SLOG(level, tag, fmt, ##__VA_ARGS__) #define SLOG(level, tag, fmt, ...) _SLOG(level, tag, fmt, ##__VA_ARGS__)
#define SLOG_TRACE(tag, fmt, ...) \ #define SLOG_TRACE(tag, fmt, ...) SLOG(sled::LogLevel::kTrace, tag, fmt, __VA_ARGS__)
SLOG(sled::LogLevel::kTrace, tag, fmt, __VA_ARGS__) #define SLOG_INFO(tag, fmt, ...) SLOG(sled::LogLevel::kInfo, tag, fmt, __VA_ARGS__)
#define SLOG_INFO(tag, fmt, ...) \ #define SLOG_DEBUG(tag, fmt, ...) SLOG(sled::LogLevel::kDebug, tag, fmt, __VA_ARGS__)
SLOG(sled::LogLevel::kInfo, tag, fmt, __VA_ARGS__) #define SLOG_WARNING(tag, fmt, ...) SLOG(sled::LogLevel::kWarning, tag, fmt, __VA_ARGS__)
#define SLOG_DEBUG(tag, fmt, ...) \ #define SLOG_ERROR(tag, fmt, ...) SLOG(sled::LogLevel::kError, tag, fmt, __VA_ARGS__)
SLOG(sled::LogLevel::kDebug, tag, fmt, __VA_ARGS__) #define SLOG_FATAL(tag, fmt, ...) SLOG(sled::LogLevel::kFatal, tag, fmt, __VA_ARGS__)
#define SLOG_WARNING(tag, fmt, ...) \
SLOG(sled::LogLevel::kWarning, tag, fmt, __VA_ARGS__)
#define SLOG_ERROR(tag, fmt, ...) \
SLOG(sled::LogLevel::kError, tag, fmt, __VA_ARGS__)
#define SLOG_FATAL(tag, fmt, ...) \
SLOG(sled::LogLevel::kFatal, tag, fmt, __VA_ARGS__)
#define SLOG_IF(cond, level, tag, fmt, ...) \ #define SLOG_IF(cond, level, tag, fmt, ...) \
do { \ do { \
if (cond) { SLOG(level, tag, fmt, __VA_ARGS__); } \ if (cond) { SLOG(level, tag, fmt, __VA_ARGS__); } \
} while (0) } while (0)
#define SLOG_ASSERT(cond, tag, fmt, ...) \ #define SLOG_ASSERT(cond, tag, fmt, ...) \
do { \ do { \
if (!(cond)) { \ if (!(cond)) { \
SLOG(sled::LogLevel::kFatal, tag, fmt, ##__VA_ARGS__); \ SLOG(sled::LogLevel::kFatal, tag, fmt, ##__VA_ARGS__); \
assert(cond); \ assert(cond); \
} \ } \
} while (0) } while (0)
#define LOGV_IF(cond, tag, fmt, ...) \ #define LOGV_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kTrace, tag, fmt, __VA_ARGS__)
SLOG_IF(cond, sled::LogLevel::kTrace, tag, fmt, __VA_ARGS__) #define LOGD_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kDebug, tag, fmt, __VA_ARGS__)
#define LOGD_IF(cond, tag, fmt, ...) \ #define LOGI_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kInfo, tag, fmt, __VA_ARGS__)
SLOG_IF(cond, sled::LogLevel::kDebug, tag, fmt, __VA_ARGS__) #define LOGW_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kWarning, tag, fmt, __VA_ARGS__)
#define LOGI_IF(cond, tag, fmt, ...) \ #define LOGE_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kError, tag, fmt, __VA_ARGS__)
SLOG_IF(cond, sled::LogLevel::kInfo, tag, fmt, __VA_ARGS__) #define LOGF_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kFatal, tag, fmt, __VA_ARGS__)
#define LOGW_IF(cond, tag, fmt, ...) \
SLOG_IF(cond, sled::LogLevel::kWarning, tag, fmt, __VA_ARGS__)
#define LOGE_IF(cond, tag, fmt, ...) \
SLOG_IF(cond, sled::LogLevel::kError, tag, fmt, __VA_ARGS__)
#define LOGF_IF(cond, tag, fmt, ...) \
SLOG_IF(cond, sled::LogLevel::kFatal, tag, fmt, __VA_ARGS__)
#define LOGV(tag, fmt, ...) \ #define LOGV(tag, fmt, ...) SLOG(sled::LogLevel::kTrace, tag, fmt, ##__VA_ARGS__)
SLOG(sled::LogLevel::kTrace, tag, fmt, ##__VA_ARGS__) #define LOGD(tag, fmt, ...) SLOG(sled::LogLevel::kDebug, tag, fmt, ##__VA_ARGS__)
#define LOGD(tag, fmt, ...) \
SLOG(sled::LogLevel::kDebug, tag, fmt, ##__VA_ARGS__)
#define LOGI(tag, fmt, ...) SLOG(sled::LogLevel::kInfo, tag, fmt, ##__VA_ARGS__) #define LOGI(tag, fmt, ...) SLOG(sled::LogLevel::kInfo, tag, fmt, ##__VA_ARGS__)
#define LOGW(tag, fmt, ...) \ #define LOGW(tag, fmt, ...) SLOG(sled::LogLevel::kWarning, tag, fmt, ##__VA_ARGS__)
SLOG(sled::LogLevel::kWarning, tag, fmt, ##__VA_ARGS__) #define LOGE(tag, fmt, ...) SLOG(sled::LogLevel::kError, tag, fmt, ##__VA_ARGS__)
#define LOGE(tag, fmt, ...) \ #define LOGF(tag, fmt, ...) SLOG(sled::LogLevel::kFatal, tag, fmt, ##__VA_ARGS__)
SLOG(sled::LogLevel::kError, tag, fmt, ##__VA_ARGS__)
#define LOGF(tag, fmt, ...) \
SLOG(sled::LogLevel::kFatal, tag, fmt, ##__VA_ARGS__)
#define ASSERT(cond, fmt, ...) SLOG_ASSERT(cond, "ASSERT", fmt, ##__VA_ARGS__) #define ASSERT(cond, fmt, ...) SLOG_ASSERT(cond, "ASSERT", fmt, ##__VA_ARGS__)
#define __LOG_EVERY_N(n, level, tag, fmt, ...) \
do { \
static int __sled_log_count##__FUNCTION__##__LINE__ = 0; \
if (__sled_log_count##__FUNCTION__##__LINE__++ % n == 0) { SLOG(level, tag, fmt, ##__VA_ARGS__); } \
} while (0)
#define LOGV_EVERY_N(n, tag, fmt, ...) __LOG_EVERY_N(n, sled::LogLevel::kTrace, tag, fmt, ##__VA_ARGS__)
#define LOGD_EVERY_N(n, tag, fmt, ...) __LOG_EVERY_N(n, sled::LogLevel::kDebug, tag, fmt, ##__VA_ARGS__)
#define LOGI_EVERY_N(n, tag, fmt, ...) __LOG_EVERY_N(n, sled::LogLevel::kInfo, tag, fmt, ##__VA_ARGS__)
#define LOGW_EVERY_N(n, tag, fmt, ...) __LOG_EVERY_N(n, sled::LogLevel::kWarning, tag, fmt, ##__VA_ARGS__)
#define LOGE_EVERY_N(n, tag, fmt, ...) __LOG_EVERY_N(n, sled::LogLevel::kError, tag, fmt, ##__VA_ARGS__)
#define LOGF_EVERY_N(n, tag, fmt, ...) __LOG_EVERY_N(n, sled::LogLevel::kFatal, tag, fmt, ##__VA_ARGS__)
#define __LOG_ONCE(level, tag, fmt, ...) \
do { \
static bool __sled_log_once##__FUNCTION__##__LINE__ = false; \
if (!__sled_log_once##__FUNCTION__##__LINE__) { \
__sled_log_once##__FUNCTION__##__LINE__ = true; \
SLOG(level, tag, fmt, ##__VA_ARGS__); \
} \
} while (0)
#define LOGV_ONCE(tag, fmt, ...) __LOG_ONCE(sled::LogLevel::kTrace, tag, fmt, ##__VA_ARGS__)
#define LOGD_ONCE(tag, fmt, ...) __LOG_ONCE(sled::LogLevel::kDebug, tag, fmt, ##__VA_ARGS__)
#define LOGI_ONCE(tag, fmt, ...) __LOG_ONCE(sled::LogLevel::kInfo, tag, fmt, ##__VA_ARGS__)
#define LOGW_ONCE(tag, fmt, ...) __LOG_ONCE(sled::LogLevel::kWarning, tag, fmt, ##__VA_ARGS__)
#define LOGE_ONCE(tag, fmt, ...) __LOG_ONCE(sled::LogLevel::kError, tag, fmt, ##__VA_ARGS__)
#define LOGF_ONCE(tag, fmt, ...) __LOG_ONCE(sled::LogLevel::kFatal, tag, fmt, ##__VA_ARGS__)
#endif// SLED_LOG_LOG_H #endif// SLED_LOG_LOG_H

View File

@ -108,21 +108,25 @@ public:
T &value_or(T &&val) & T &value_or(T &&val) &
{ {
if (!ok()) return val; if (!ok()) return val;
return **this;
} }
T const &value_or(T &&val) const & T const &value_or(T &&val) const &
{ {
if (!ok()) return val; if (!ok()) return val;
return **this;
} }
T &&value_or(T &&val) && T &&value_or(T &&val) &&
{ {
if (!ok()) return val; if (!ok()) return std::forward<T>(val);
return std::move(**this);
} }
T const &&value_or(T &&val) const && T const &&value_or(T &&val) const &&
{ {
if (!ok()) return val; if (!ok()) return std::forward<T>(val);
return std::move(**this);
} }
Status const &status() const & { return status_; } Status const &status() const & { return status_; }

View File

@ -10,11 +10,11 @@
#include "sled/ref_counted_base.h" #include "sled/ref_counted_base.h"
#include "sled/scoped_refptr.h" #include "sled/scoped_refptr.h"
#include <functional>
namespace sled { namespace sled {
class PendingTaskSafetyFlag final class PendingTaskSafetyFlag final : public sled::RefCountedNonVirtual<PendingTaskSafetyFlag> {
: public sled::RefCountedNonVirtual<PendingTaskSafetyFlag> {
public: public:
static sled::scoped_refptr<PendingTaskSafetyFlag> Create(); static sled::scoped_refptr<PendingTaskSafetyFlag> Create();
static sled::scoped_refptr<PendingTaskSafetyFlag> CreateDetached(); static sled::scoped_refptr<PendingTaskSafetyFlag> CreateDetached();
@ -29,11 +29,36 @@ protected:
explicit PendingTaskSafetyFlag(bool alive) : alive_(alive) {} explicit PendingTaskSafetyFlag(bool alive) : alive_(alive) {}
private: private:
static sled::scoped_refptr<PendingTaskSafetyFlag> static sled::scoped_refptr<PendingTaskSafetyFlag> CreateInternal(bool alive);
CreateInternal(bool alive);
bool alive_ = true; bool alive_ = true;
}; };
class ScopedTaskSafety final {
public:
ScopedTaskSafety() = default;
explicit ScopedTaskSafety(scoped_refptr<PendingTaskSafetyFlag> flag) : flag_(std::move(flag)) {}
~ScopedTaskSafety() { flag_->SetNotAlive(); }
void reset(scoped_refptr<PendingTaskSafetyFlag> new_flag = PendingTaskSafetyFlag::Create())
{
flag_->SetNotAlive();
flag_ = std::move(new_flag);
}
private:
scoped_refptr<PendingTaskSafetyFlag> flag_;
};
inline std::function<void()>
SafeTask(scoped_refptr<PendingTaskSafetyFlag> flag, std::function<void()> task)
{
return [flag, task]() mutable {
if (flag->alive()) { std::move(task)(); }
};
}
}// namespace sled }// namespace sled
#endif// SLED_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H #endif// SLED_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H

View File

@ -1,7 +1,9 @@
#pragma once #pragma once
#include "sled/scoped_refptr.h"
#ifndef SLED_TIMER_QUEUE_TIMEOUT_H #ifndef SLED_TIMER_QUEUE_TIMEOUT_H
#define SLED_TIMER_QUEUE_TIMEOUT_H #define SLED_TIMER_QUEUE_TIMEOUT_H
#include "sled/task_queue/pending_task_safety_flag.h"
#include "sled/task_queue/task_queue_base.h" #include "sled/task_queue/task_queue_base.h"
#include "sled/timer/timeout.h" #include "sled/timer/timeout.h"
#include <limits> #include <limits>
@ -12,28 +14,24 @@ typedef uint64_t TimeMs;
class TaskQueueTimeoutFactory { class TaskQueueTimeoutFactory {
public: public:
TaskQueueTimeoutFactory( TaskQueueTimeoutFactory(sled::TaskQueueBase &task_queue,
sled::TaskQueueBase &task_queue, std::function<TimeMs()> get_time,
std::function<TimeMs()> get_time, std::function<void(TimeoutID timeout_id)> on_expired)
std::function<void(TimeoutID timeout_id)> on_expired)
: task_queue_(task_queue), : task_queue_(task_queue),
get_time_(get_time), get_time_(get_time),
on_expired_(on_expired) on_expired_(on_expired)
{} {}
std::unique_ptr<Timeout> std::unique_ptr<Timeout>
CreateTimeout(sled::TaskQueueBase::DelayPrecision precision = CreateTimeout(sled::TaskQueueBase::DelayPrecision precision = sled::TaskQueueBase::DelayPrecision::kHigh)
sled::TaskQueueBase::DelayPrecision::kHigh)
{ {
return std::unique_ptr<TaskQueueTimeout>( return std::unique_ptr<TaskQueueTimeout>(new TaskQueueTimeout(*this, precision));
new TaskQueueTimeout(*this, precision));
} }
private: private:
class TaskQueueTimeout : public Timeout { class TaskQueueTimeout : public Timeout {
public: public:
TaskQueueTimeout(TaskQueueTimeoutFactory &parent, TaskQueueTimeout(TaskQueueTimeoutFactory &parent, sled::TaskQueueBase::DelayPrecision precision);
sled::TaskQueueBase::DelayPrecision precision);
~TaskQueueTimeout() override; ~TaskQueueTimeout() override;
void Start(DurationMs duration, TimeoutID timeout_id) override; void Start(DurationMs duration, TimeoutID timeout_id) override;
void Stop() override; void Stop() override;
@ -44,6 +42,7 @@ private:
TimeMs posted_task_expiration_ = std::numeric_limits<TimeMs>::max(); TimeMs posted_task_expiration_ = std::numeric_limits<TimeMs>::max();
TimeMs timeout_expiration_ = std::numeric_limits<TimeMs>::max(); TimeMs timeout_expiration_ = std::numeric_limits<TimeMs>::max();
TimeoutID timeout_id_ = TimeoutID(0); TimeoutID timeout_id_ = TimeoutID(0);
scoped_refptr<PendingTaskSafetyFlag> safety_flag_;
}; };
sled::TaskQueueBase &task_queue_; sled::TaskQueueBase &task_queue_;

View File

@ -1,29 +0,0 @@
/**
* @file : {{FILE}}
* @created : {{TIMESTAMP}}
* @license : {{LICENSE}}
**/
#ifndef{{MACRO_GUARD } }
#define{{MACRO_GUARD } }
namespace {
{
CURSOR
}
}// namespace
{
class {
{
CAMEL_CLASS
}
} {
public:
};
}// namespace
#endif// {{MACRO_GUARD}}

View File

@ -1,5 +1,6 @@
#include "sled/profiling/profiling.h" #include "sled/profiling/profiling.h"
#include <uprofile.h>
// #include <uprofile.h>
namespace sled { namespace sled {
Profiling * Profiling *
@ -12,7 +13,7 @@ Profiling::Instance()
bool bool
Profiling::Start(const std::string &file) Profiling::Start(const std::string &file)
{ {
uprofile::start(file.c_str()); // uprofile::start(file.c_str());
started_ = true; started_ = true;
return true; return true;
} }
@ -20,53 +21,53 @@ Profiling::Start(const std::string &file)
void void
Profiling::Stop() Profiling::Stop()
{ {
uprofile::stop(); // uprofile::stop();
} }
void void
Profiling::TimeBegin(const std::string &name) Profiling::TimeBegin(const std::string &name)
{ {
if (!started_) return; if (!started_) return;
uprofile::timeBegin(name); // uprofile::timeBegin(name);
} }
void void
Profiling::TimeEnd(const std::string &name) Profiling::TimeEnd(const std::string &name)
{ {
if (!started_) return; if (!started_) return;
uprofile::timeEnd(name); // uprofile::timeEnd(name);
} }
void void
Profiling::StartProcessMemoryMonitoring(int period_ms) Profiling::StartProcessMemoryMonitoring(int period_ms)
{ {
if (!started_) return; if (!started_) return;
uprofile::startProcessMemoryMonitoring(period_ms); // uprofile::startProcessMemoryMonitoring(period_ms);
} }
void void
Profiling::StartSystemMemoryMonitoring(int period_ms) Profiling::StartSystemMemoryMonitoring(int period_ms)
{ {
if (!started_) return; if (!started_) return;
uprofile::startSystemMemoryMonitoring(period_ms); // uprofile::startSystemMemoryMonitoring(period_ms);
} }
void void
Profiling::StartCPUUsageMonitoring(int period_ms) Profiling::StartCPUUsageMonitoring(int period_ms)
{ {
if (!started_) return; if (!started_) return;
uprofile::startCPUUsageMonitoring(period_ms); // uprofile::startCPUUsageMonitoring(period_ms);
} }
void void
Profiling::GetSystemMemory(int &total_mem, int &available_mem, int &free_mem) Profiling::GetSystemMemory(int &total_mem, int &available_mem, int &free_mem)
{ {
uprofile::getSystemMemory(total_mem, available_mem, free_mem); // uprofile::getSystemMemory(total_mem, available_mem, free_mem);
} }
void void
Profiling::GetProcessMemory(int &rss, int &shared) Profiling::GetProcessMemory(int &rss, int &shared)
{ {
uprofile::getProcessMemory(rss, shared); // uprofile::getProcessMemory(rss, shared);
} }
}// namespace sled }// namespace sled

View File

@ -6,8 +6,7 @@ sled::scoped_refptr<PendingTaskSafetyFlag>
PendingTaskSafetyFlag::CreateInternal(bool alive) PendingTaskSafetyFlag::CreateInternal(bool alive)
{ {
// Explicit new, to access private constructor. // Explicit new, to access private constructor.
return sled::scoped_refptr<PendingTaskSafetyFlag>( return sled::scoped_refptr<PendingTaskSafetyFlag>(new PendingTaskSafetyFlag(alive));
new PendingTaskSafetyFlag(alive));
} }
sled::scoped_refptr<PendingTaskSafetyFlag> sled::scoped_refptr<PendingTaskSafetyFlag>
@ -31,7 +30,7 @@ PendingTaskSafetyFlag::CreateDetachedInactive()
void void
PendingTaskSafetyFlag::SetNotAlive() PendingTaskSafetyFlag::SetNotAlive()
{ {
alive_ = true; alive_ = false;
} }
void void

View File

@ -1,15 +1,17 @@
#include "sled/timer/task_queue_timeout.h" #include "sled/timer/task_queue_timeout.h"
#include "sled/log/log.h" #include "sled/log/log.h"
#include "sled/task_queue/pending_task_safety_flag.h"
#include "sled/units/time_delta.h" #include "sled/units/time_delta.h"
namespace sled { namespace sled {
TaskQueueTimeoutFactory::TaskQueueTimeout::TaskQueueTimeout(TaskQueueTimeoutFactory &parent, TaskQueueTimeoutFactory::TaskQueueTimeout::TaskQueueTimeout(TaskQueueTimeoutFactory &parent,
sled::TaskQueueBase::DelayPrecision precision) sled::TaskQueueBase::DelayPrecision precision)
: parent_(parent), : parent_(parent),
precision_(precision) precision_(precision),
safety_flag_(PendingTaskSafetyFlag::Create())
{} {}
TaskQueueTimeoutFactory::TaskQueueTimeout::~TaskQueueTimeout() {} TaskQueueTimeoutFactory::TaskQueueTimeout::~TaskQueueTimeout() { safety_flag_->SetNotAlive(); }
void void
TaskQueueTimeoutFactory::TaskQueueTimeout::Start(DurationMs duration_ms, TimeoutID timeout_id) TaskQueueTimeoutFactory::TaskQueueTimeout::Start(DurationMs duration_ms, TimeoutID timeout_id)
@ -23,32 +25,42 @@ TaskQueueTimeoutFactory::TaskQueueTimeout::Start(DurationMs duration_ms, Timeout
LOGV("timer", LOGV("timer",
"New timeout duration is less than scheduled - " "New timeout duration is less than scheduled - "
"ghosting old delayed task"); "ghosting old delayed task");
safety_flag_->SetNotAlive();
safety_flag_ = PendingTaskSafetyFlag::Create();
} }
posted_task_expiration_ = timeout_expiration_; posted_task_expiration_ = timeout_expiration_;
auto safety_flag = safety_flag_;
parent_.task_queue_.PostDelayedTaskWithPrecision( parent_.task_queue_.PostDelayedTaskWithPrecision(
precision_, precision_,
[timeout_id, this]() { SafeTask(safety_flag_,
LOGV("timer", "Timeout expired: {}", timeout_id); [timeout_id, this]() {
ASSERT(posted_task_expiration_ != std::numeric_limits<TimeMs>::max(), ""); // if (timeout_id != this->timeout_id_) { return; }
posted_task_expiration_ = std::numeric_limits<TimeMs>::max(); LOGV("timer", "Timeout expired: {}", timeout_id);
// FIXME: this is a bug, the posted_task_expiration_ should be reset to max
ASSERT(posted_task_expiration_ != std::numeric_limits<TimeMs>::max(), "");
posted_task_expiration_ = std::numeric_limits<TimeMs>::max();
if (timeout_expiration_ == std::numeric_limits<TimeMs>::max()) { if (timeout_expiration_ == std::numeric_limits<TimeMs>::max()) {
// cancelled timer // cancelled timer
// do nothing // do nothing
} else { } else {
const TimeMs now = parent_.get_time_(); const TimeMs now = parent_.get_time_();
if (timeout_expiration_ <= now) { const DurationMs remaining = timeout_expiration_ - now;
timeout_expiration_ = std::numeric_limits<TimeMs>::max(); bool is_expired = timeout_expiration_ <= now;
LOGV("timer", "Timeout Triggered: {}", timeout_id);
parent_.on_expired_(timeout_id_); timeout_expiration_ = std::numeric_limits<TimeMs>::max();
} else {
const DurationMs remaining = timeout_expiration_ - now; if (!is_expired) {
timeout_expiration_ = std::numeric_limits<TimeMs>::max(); // continue wait
Start(remaining, timeout_id); Start(remaining, timeout_id);
} } else {
} LOGV("timer", "Timeout Triggered: {}", timeout_id);
}, parent_.on_expired_(timeout_id_);
}
}
}),
sled::TimeDelta::Millis(duration_ms)); sled::TimeDelta::Millis(duration_ms));
} }

View File

@ -47,6 +47,7 @@ Timer::Stop()
{ {
if (is_running()) { if (is_running()) {
timeout_->Stop(); timeout_->Stop();
generation_ = TimerGeneration(generation_ + 1);
expiration_count_ = 0; expiration_count_ = 0;
is_running_ = false; is_running_ = false;
} }
@ -58,6 +59,7 @@ Timer::Trigger(TimerGeneration generation)
if (!is_running_ || generation != generation_) { return; } if (!is_running_ || generation != generation_) { return; }
++expiration_count_; ++expiration_count_;
is_running_ = false; is_running_ = false;
// if max_restarts > exppiration_count_ then restart // if max_restarts > exppiration_count_ then restart
{ {
is_running_ = true; is_running_ = true;
@ -82,12 +84,10 @@ TimerManager::CreateTimer(const std::string &name, Timer::OnExpired on_expired)
next_id_ = TimerID(next_id_ + 1); next_id_ = TimerID(next_id_ + 1);
TimerID id = next_id_; TimerID id = next_id_;
std::unique_ptr<Timeout> timeout = std::unique_ptr<Timeout> timeout = timeout_creator_(sled::TaskQueueBase::DelayPrecision::kHigh);
timeout_creator_(sled::TaskQueueBase::DelayPrecision::kHigh);
auto timer = std::unique_ptr<Timer>(new Timer( auto timer = std::unique_ptr<Timer>(new Timer(
id, name, std::move(on_expired), id, name, std::move(on_expired),
/* ungrgister_handler=*/[this, id]() { timers_.erase(id); }, /* ungrgister_handler=*/[this, id]() { timers_.erase(id); }, std::move(timeout)));
std::move(timeout)));
timers_[id] = timer.get(); timers_[id] = timer.get();
return timer; return timer;
} }