feat merge
This commit is contained in:
58
include/sled/apply.h
Normal file
58
include/sled/apply.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#ifndef SLED_APPLY_H
|
||||
#define SLED_APPLY_H
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
namespace sled {
|
||||
namespace detail {
|
||||
template<int... Seq>
|
||||
struct Sequence {};
|
||||
|
||||
template<int N, int... Seq>
|
||||
struct MakeSeq : MakeSeq<N - 1, N - 1, Seq...> {};
|
||||
|
||||
template<int... Seq>
|
||||
struct MakeSeq<0, Seq...> {
|
||||
using type = Sequence<Seq...>;
|
||||
};
|
||||
|
||||
template<typename ReturnT, typename Func, typename Tuple, int... Seq>
|
||||
ReturnT
|
||||
ApplyImpl(const Func &func, const Tuple &tuple, const Sequence<Seq...> &)
|
||||
{
|
||||
return std::bind(func, std::get<Seq>(tuple)...)();
|
||||
}
|
||||
|
||||
struct VoidTag {};
|
||||
|
||||
}// namespace detail
|
||||
|
||||
template<typename ReturnT,
|
||||
typename Func,
|
||||
typename Tuple,
|
||||
typename std::enable_if<!std::is_void<ReturnT>::value, ReturnT>::type
|
||||
* = nullptr>
|
||||
ReturnT
|
||||
apply(const Func &func, const Tuple &tuple)
|
||||
{
|
||||
return detail::ApplyImpl<ReturnT>(
|
||||
func, tuple,
|
||||
typename detail::MakeSeq<std::tuple_size<Tuple>::value>::type());
|
||||
}
|
||||
|
||||
template<typename ReturnT = void,
|
||||
typename Func,
|
||||
typename Tuple,
|
||||
typename std::enable_if<std::is_void<ReturnT>::value,
|
||||
detail::VoidTag>::type * = nullptr>
|
||||
void
|
||||
apply(const Func &func, const Tuple &tuple)
|
||||
{
|
||||
detail::ApplyImpl<ReturnT>(
|
||||
func, tuple,
|
||||
typename detail::MakeSeq<std::tuple_size<Tuple>::value>::type());
|
||||
}
|
||||
|
||||
}// namespace sled
|
||||
#endif// SLED_APPLY_H
|
||||
24
include/sled/filesystem/path.h
Normal file
24
include/sled/filesystem/path.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#ifndef SLED_FILESYSTEM_PATH_H
|
||||
#define SLED_FILESYSTEM_PATH_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sled {
|
||||
class Path {
|
||||
public:
|
||||
// cwd = current working directory
|
||||
static Path Current();
|
||||
static Path Home();
|
||||
static Path TempDir();
|
||||
|
||||
Path();
|
||||
Path(const std::string &path);
|
||||
|
||||
std::string ToString() const { return path_; };
|
||||
|
||||
private:
|
||||
std::string path_;
|
||||
};
|
||||
}// namespace sled
|
||||
#endif// SLED_FILESYSTEM_PATH_H
|
||||
13
include/sled/filesystem/temporary_file.h
Normal file
13
include/sled/filesystem/temporary_file.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#ifndef SLED_FILESYSTEM_TEMPORARY_FILE_H
|
||||
#define SLED_FILESYSTEM_TEMPORARY_FILE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sled {
|
||||
class TemporaryFile {
|
||||
TemporaryFile();
|
||||
TemporaryFile(const std::string &tmp_dir);
|
||||
};
|
||||
}// namespace sled
|
||||
#endif// SLED_FILESYSTEM_TEMPORARY_FILE_H
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef SLED_LOG_LOG_H
|
||||
#define SLED_LOG_LOG_H
|
||||
#include "sled/system/location.h"
|
||||
#include <assert.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace sled {
|
||||
@@ -19,6 +20,7 @@ enum class LogLevel {
|
||||
kError,
|
||||
kFatal,
|
||||
};
|
||||
void SetLogLevel(LogLevel level);
|
||||
|
||||
void Log(LogLevel level,
|
||||
const char *tag,
|
||||
|
||||
70
include/sled/sled.h
Normal file
70
include/sled/sled.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
#ifndef SLED_SLED_H
|
||||
#define SLED_SLED_H
|
||||
// filesystem
|
||||
#include "sled/filesystem/path.h"
|
||||
#include "sled/filesystem/temporary_file.h"
|
||||
|
||||
// log
|
||||
#include "sled/log/log.h"
|
||||
|
||||
// network
|
||||
#include "sled/network/async_resolver.h"
|
||||
#include "sled/network/async_resolver_interface.h"
|
||||
#include "sled/network/ip_address.h"
|
||||
#include "sled/network/null_socket_server.h"
|
||||
#include "sled/network/physical_socket_server.h"
|
||||
#include "sled/network/socket.h"
|
||||
#include "sled/network/socket_address.h"
|
||||
#include "sled/network/socket_factory.h"
|
||||
#include "sled/network/socket_server.h"
|
||||
|
||||
// numerics
|
||||
#include "sled/numerics/divide_round.h"
|
||||
|
||||
// strings
|
||||
#include "sled/strings/base64.h"
|
||||
#include "sled/strings/utils.h"
|
||||
|
||||
// synchorization
|
||||
#include "sled/synchronization/event.h"
|
||||
#include "sled/synchronization/mutex.h"
|
||||
#include "sled/synchronization/one_time_event.h"
|
||||
#include "sled/synchronization/thread_local.h"
|
||||
// system
|
||||
#include "sled/system/fiber/scheduler.h"
|
||||
#include "sled/system/fiber/wait_group.h"
|
||||
#include "sled/system/location.h"
|
||||
#include "sled/system/thread.h"
|
||||
#include "sled/system/thread_pool.h"
|
||||
|
||||
// timer
|
||||
#include "sled/timer/task_queue_timeout.h"
|
||||
#include "sled/timer/timeout.h"
|
||||
#include "sled/timer/timer.h"
|
||||
|
||||
// other
|
||||
#include "sled/any.h"
|
||||
#include "sled/apply.h"
|
||||
#include "sled/buffer.h"
|
||||
#include "sled/byte_order.h"
|
||||
#include "sled/cleanup.h"
|
||||
#include "sled/make_ref_counted.h"
|
||||
#include "sled/operations_chain.h"
|
||||
#include "sled/optional.h"
|
||||
#include "sled/random.h"
|
||||
#include "sled/ref_count.h"
|
||||
#include "sled/ref_counted_base.h"
|
||||
#include "sled/ref_counted_object.h"
|
||||
#include "sled/ref_counter.h"
|
||||
#include "sled/scoped_refptr.h"
|
||||
// #include "sled/sequence_checker.h"
|
||||
#include "sled/sigslot.h"
|
||||
#include "sled/status.h"
|
||||
#include "sled/status_or.h"
|
||||
#include "sled/system_time.h"
|
||||
#include "sled/time_utils.h"
|
||||
#include "sled/variant.h"
|
||||
|
||||
#include "inja.hpp"
|
||||
#endif// SLED_SLED_H
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
|
||||
StatusOr(StatusOr &&other)
|
||||
: status_(std::move(other.status_)),
|
||||
value_(std::move(value_))
|
||||
value_(std::move(other.value_))
|
||||
{
|
||||
other.status_ = MakeDefaultStatus();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,29 @@
|
||||
#pragma once
|
||||
#ifndef SLED_STRINGS_UTILS_H
|
||||
#define SLED_STRINGS_UTILS_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace sled {
|
||||
|
||||
char ToLower(char c);
|
||||
char ToUpper(char c);
|
||||
std::string ToLower(const std::string &str);
|
||||
std::string ToUpper(const std::string &str);
|
||||
std::string ToHex(const std::string &str);
|
||||
std::string StrJoin(const std::vector<std::string> &strings,
|
||||
const std::string &delim,
|
||||
bool skip_empty = false);
|
||||
std::vector<std::string> StrSplit(const std::string &str,
|
||||
const std::string &delim,
|
||||
bool skip_empty = false);
|
||||
std::string Trim(const std::string &str, const std::string &chars = " \t\n\r");
|
||||
std::string TrimLeft(const std::string &str,
|
||||
const std::string &chars = " \t\n\r");
|
||||
std::string TrimRight(const std::string &str,
|
||||
const std::string &chars = " \t\n\r");
|
||||
bool EndsWith(const std::string &str, const std::string &suffix);
|
||||
bool StartsWith(const std::string &str, const std::string &prefix);
|
||||
|
||||
} // namespace sled
|
||||
#endif // SLED_STRINGS_UTILS_H
|
||||
}// namespace sled
|
||||
#endif// SLED_STRINGS_UTILS_H
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
#include "marl/conditionvariable.h"
|
||||
#ifndef SLED_SYNCHRONIZATION_MUTEX_H
|
||||
#define SLED_SYNCHRONIZATION_MUTEX_H
|
||||
|
||||
#include "sled/units/time_delta.h"
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <marl/mutex.h>
|
||||
#include <mutex>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -31,24 +33,26 @@ struct HasLockAndUnlock {
|
||||
};
|
||||
}// namespace internal
|
||||
|
||||
class Mutex final {
|
||||
public:
|
||||
Mutex() = default;
|
||||
Mutex(const Mutex &) = delete;
|
||||
Mutex &operator=(const Mutex &) = delete;
|
||||
using Mutex = marl::mutex;
|
||||
|
||||
inline void Lock() { impl_.lock(); };
|
||||
|
||||
inline bool TryLock() { return impl_.try_lock(); }
|
||||
|
||||
inline void AssertHeld() {}
|
||||
|
||||
inline void Unlock() { impl_.unlock(); }
|
||||
|
||||
private:
|
||||
std::mutex impl_;
|
||||
friend class ConditionVariable;
|
||||
};
|
||||
// class Mutex final {
|
||||
// public:
|
||||
// Mutex() = default;
|
||||
// Mutex(const Mutex &) = delete;
|
||||
// Mutex &operator=(const Mutex &) = delete;
|
||||
//
|
||||
// inline void Lock() { impl_.lock(); };
|
||||
//
|
||||
// inline bool TryLock() { return impl_.try_lock(); }
|
||||
//
|
||||
// inline void AssertHeld() {}
|
||||
//
|
||||
// inline void Unlock() { impl_.unlock(); }
|
||||
//
|
||||
// private:
|
||||
// std::mutex impl_;
|
||||
// friend class ConditionVariable;
|
||||
// };
|
||||
|
||||
class RecursiveMutex final {
|
||||
public:
|
||||
@@ -85,7 +89,22 @@ private:
|
||||
friend class ConditionVariable;
|
||||
};
|
||||
|
||||
using MutexLock = LockGuard<Mutex>;
|
||||
class MutexGuard final {
|
||||
public:
|
||||
MutexGuard(Mutex *mutex) : lock_(*mutex) {}
|
||||
|
||||
MutexGuard(const MutexGuard &) = delete;
|
||||
MutexGuard &operator=(const MutexGuard &) = delete;
|
||||
|
||||
private:
|
||||
friend class ConditionVariable;
|
||||
marl::lock lock_;
|
||||
};
|
||||
|
||||
using MutexLock = MutexGuard;
|
||||
// using MutexGuard = marl::lock;
|
||||
// using MutexLock = LockGuard<Mutex>;
|
||||
// using MutexGuard = LockGuard<Mutex>;
|
||||
using RecursiveMutexLock = LockGuard<RecursiveMutex>;
|
||||
|
||||
// class MutexLock final {
|
||||
@@ -120,44 +139,77 @@ using RecursiveMutexLock = LockGuard<RecursiveMutex>;
|
||||
class ConditionVariable final {
|
||||
public:
|
||||
static constexpr TimeDelta kForever = TimeDelta::PlusInfinity();
|
||||
ConditionVariable() = default;
|
||||
ConditionVariable(const ConditionVariable &) = delete;
|
||||
ConditionVariable &operator=(const ConditionVariable &) = delete;
|
||||
|
||||
template<typename Predicate>
|
||||
inline bool Wait(LockGuard<Mutex> &guard, Predicate pred)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock);
|
||||
cv_.wait(lock, pred);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Predicate>
|
||||
inline bool
|
||||
WaitFor(LockGuard<Mutex> &guard, TimeDelta timeout, Predicate pred)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock);
|
||||
if (timeout == kForever) {
|
||||
cv_.wait(lock, pred);
|
||||
return true;
|
||||
} else {
|
||||
return cv_.wait_for(lock, std::chrono::milliseconds(timeout.ms()),
|
||||
pred);
|
||||
}
|
||||
}
|
||||
|
||||
// template<typename Predicate>
|
||||
// bool WaitUntil(Mutex *mutex, TimeDelta timeout, Predicate pred)
|
||||
// {}
|
||||
// inline ConditionVariable();
|
||||
|
||||
inline void NotifyOne() { cv_.notify_one(); }
|
||||
|
||||
inline void NotifyAll() { cv_.notify_all(); }
|
||||
|
||||
template<typename Predicate>
|
||||
inline void Wait(MutexLock &lock, Predicate &&pred)
|
||||
{
|
||||
cv_.wait(lock, std::forward<Predicate>(pred));
|
||||
}
|
||||
|
||||
template<typename Predicate>
|
||||
inline bool WaitFor(MutexLock &lock, TimeDelta timeout, Predicate &&pred)
|
||||
{
|
||||
if (timeout == TimeDelta::PlusInfinity()) {
|
||||
cv_.wait(lock.lock_, std::forward<Predicate>(pred));
|
||||
return true;
|
||||
} else {
|
||||
return cv_.wait_for(lock.lock_,
|
||||
std::chrono::milliseconds(timeout.ms()),
|
||||
std::forward<Predicate>(pred));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::condition_variable cv_;
|
||||
marl::ConditionVariable cv_;
|
||||
};
|
||||
|
||||
// class ConditionVariable final {
|
||||
// public:
|
||||
// static constexpr TimeDelta kForever = TimeDelta::PlusInfinity();
|
||||
// ConditionVariable() = default;
|
||||
// ConditionVariable(const ConditionVariable &) = delete;
|
||||
// ConditionVariable &operator=(const ConditionVariable &) = delete;
|
||||
//
|
||||
// template<typename Predicate>
|
||||
// inline bool Wait(LockGuard<Mutex> &guard, Predicate pred)
|
||||
// {
|
||||
// std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock);
|
||||
// cv_.wait(lock, pred);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// template<typename Predicate>
|
||||
// inline bool
|
||||
// WaitFor(LockGuard<Mutex> &guard, TimeDelta timeout, Predicate pred)
|
||||
// {
|
||||
// std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock);
|
||||
// if (timeout == kForever) {
|
||||
// cv_.wait(lock, pred);
|
||||
// return true;
|
||||
// } else {
|
||||
// return cv_.wait_for(lock, std::chrono::milliseconds(timeout.ms()),
|
||||
// pred);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // template<typename Predicate>
|
||||
// // bool WaitUntil(Mutex *mutex, TimeDelta timeout, Predicate pred)
|
||||
// // {}
|
||||
//
|
||||
// inline void NotifyOne() { cv_.notify_one(); }
|
||||
//
|
||||
// inline void NotifyAll() { cv_.notify_all(); }
|
||||
//
|
||||
// private:
|
||||
// std::condition_variable cv_;
|
||||
// };
|
||||
|
||||
}// namespace sled
|
||||
|
||||
#endif// SLED_SYNCHRONIZATION_MUTEX_H
|
||||
|
||||
@@ -38,7 +38,9 @@ private:
|
||||
template<typename T>
|
||||
class ThreadLocal final {
|
||||
public:
|
||||
ThreadLocal() : key_(detail::ThreadLocalManager::NextKey()) {}
|
||||
static_assert(std::is_pointer<T>::value, "T must be a pointer type");
|
||||
|
||||
inline ThreadLocal() : key_(detail::ThreadLocalManager::NextKey()) {}
|
||||
|
||||
~ThreadLocal()
|
||||
{ /*detail::ThreadLocalManager::Instance().Delete(key_); */
|
||||
|
||||
45
include/sled/system/fiber/scheduler.h
Normal file
45
include/sled/system/fiber/scheduler.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#ifndef SLED_SYSTEM_FIBER_SCHEDULER_H
|
||||
#define SLED_SYSTEM_FIBER_SCHEDULER_H
|
||||
#include <marl/defer.h>
|
||||
#include <marl/scheduler.h>
|
||||
#include <marl/task.h>
|
||||
|
||||
namespace sled {
|
||||
using Scheduler = marl::Scheduler;
|
||||
|
||||
// schedule() schedules the task T to be asynchronously called using the
|
||||
// currently bound scheduler.
|
||||
inline void
|
||||
Schedule(marl::Task &&t)
|
||||
{
|
||||
MARL_ASSERT_HAS_BOUND_SCHEDULER("marl::schedule");
|
||||
auto scheduler = marl::Scheduler::get();
|
||||
scheduler->enqueue(std::move(t));
|
||||
}
|
||||
|
||||
// schedule() schedules the function f to be asynchronously called with the
|
||||
// given arguments using the currently bound scheduler.
|
||||
template<typename Function, typename... Args>
|
||||
inline void
|
||||
Schedule(Function &&f, Args &&...args)
|
||||
{
|
||||
MARL_ASSERT_HAS_BOUND_SCHEDULER("marl::schedule");
|
||||
auto scheduler = marl::Scheduler::get();
|
||||
scheduler->enqueue(marl::Task(
|
||||
std::bind(std::forward<Function>(f), std::forward<Args>(args)...)));
|
||||
}
|
||||
|
||||
// schedule() schedules the function f to be asynchronously called using the
|
||||
// currently bound scheduler.
|
||||
template<typename Function>
|
||||
inline void
|
||||
Schedule(Function &&f)
|
||||
{
|
||||
MARL_ASSERT_HAS_BOUND_SCHEDULER("marl::schedule");
|
||||
auto scheduler = marl::Scheduler::get();
|
||||
scheduler->enqueue(marl::Task(std::forward<Function>(f)));
|
||||
}
|
||||
}// namespace sled
|
||||
|
||||
#endif// SLED_SYSTEM_FIBER_SCHEDULER_H
|
||||
26
include/sled/system/fiber/wait_group.h
Normal file
26
include/sled/system/fiber/wait_group.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#ifndef SLED_SYSTEM_FIBER_WAIT_GROUP_H
|
||||
#define SLED_SYSTEM_FIBER_WAIT_GROUP_H
|
||||
#include <marl/waitgroup.h>
|
||||
|
||||
namespace sled {
|
||||
|
||||
class WaitGroup final {
|
||||
public:
|
||||
inline WaitGroup(unsigned int count = 0,
|
||||
marl::Allocator *allocator = marl::Allocator::Default)
|
||||
: wg_(new marl::WaitGroup(count, allocator))
|
||||
{}
|
||||
|
||||
inline void Add(unsigned int count = 1) const { wg_->add(count); };
|
||||
|
||||
inline bool Done() const { return wg_->done(); }
|
||||
|
||||
inline void Wait() const { wg_->wait(); }
|
||||
|
||||
private:
|
||||
mutable std::shared_ptr<marl::WaitGroup> wg_;
|
||||
};
|
||||
}// namespace sled
|
||||
|
||||
#endif// SLED_SYSTEM_FIBER_WAIT_GROUP_H
|
||||
@@ -16,15 +16,20 @@ class Location final {
|
||||
public:
|
||||
Location() = delete;
|
||||
|
||||
Location(const char *file_name, int file_line, const char *function);
|
||||
static Location Current(const char *file_name = __builtin_FILE(),
|
||||
int file_line = __builtin_LINE(),
|
||||
const char *function = __builtin_FUNCTION());
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
Location(const char *file_name, int file_line, const char *function);
|
||||
const char *file() const { return file_name; };
|
||||
|
||||
int line() const { return file_line; };
|
||||
|
||||
const char *func() const { return function; };
|
||||
|
||||
private:
|
||||
const char *file_name;
|
||||
int file_line;
|
||||
const char *function;
|
||||
@@ -32,6 +37,6 @@ private:
|
||||
|
||||
}// namespace sled
|
||||
|
||||
#define SLED_FROM_HERE sled::Location::Current();
|
||||
#define SLED_FROM_HERE sled::Location::Current()
|
||||
|
||||
#endif// SLED_SYSTEM_LOCATION_H
|
||||
|
||||
34
include/sled/system/thread_pool.h
Normal file
34
include/sled/system/thread_pool.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#ifndef SLED_SYSTEM_THREAD_POOL_H
|
||||
#define SLED_SYSTEM_THREAD_POOL_H
|
||||
#include "sled/system/fiber/scheduler.h"
|
||||
#include <functional>
|
||||
#include <future>
|
||||
|
||||
namespace sled {
|
||||
class ThreadPool final {
|
||||
public:
|
||||
/**
|
||||
* @param num_threads The number of threads to create in the thread pool. If
|
||||
* -1, the number of threads will be equal to the number of hardware threads
|
||||
**/
|
||||
ThreadPool(int num_threads = -1);
|
||||
~ThreadPool();
|
||||
|
||||
template<typename F, typename... Args>
|
||||
auto submit(F &&f, Args &&...args) -> std::future<decltype(f(args...))>
|
||||
{
|
||||
std::function<decltype(f(args...))()> func =
|
||||
std::bind(std::forward<F>(f), std::forward<Args>(args)...);
|
||||
auto task_ptr =
|
||||
std::make_shared<std::packaged_task<decltype(f(args...))()>>(func);
|
||||
scheduler->enqueue(marl::Task([task_ptr]() { (*task_ptr)(); }));
|
||||
return task_ptr->get_future();
|
||||
}
|
||||
|
||||
private:
|
||||
sled::Scheduler *scheduler;
|
||||
};
|
||||
|
||||
}// namespace sled
|
||||
#endif// SLED_SYSTEM_THREAD_POOL_H
|
||||
@@ -30,21 +30,21 @@ public:
|
||||
|
||||
virtual void Delete() = 0;
|
||||
|
||||
void PostTask(std::function<void()> &&task,
|
||||
const Location &location = Location::Current())
|
||||
inline void PostTask(std::function<void()> &&task,
|
||||
const Location &location = Location::Current())
|
||||
{
|
||||
PostTaskImpl(std::move(task), PostTaskTraits{}, location);
|
||||
}
|
||||
|
||||
void PostDelayedTask(std::function<void()> &&task,
|
||||
TimeDelta delay,
|
||||
const Location &location = Location::Current())
|
||||
inline void PostDelayedTask(std::function<void()> &&task,
|
||||
TimeDelta delay,
|
||||
const Location &location = Location::Current())
|
||||
{
|
||||
PostDelayedTaskImpl(std::move(task), delay, PostDelayedTaskTraits{},
|
||||
location);
|
||||
}
|
||||
|
||||
void
|
||||
inline void
|
||||
PostDelayedHighPrecisionTask(std::function<void()> &&task,
|
||||
TimeDelta delay,
|
||||
const Location &location = Location::Current())
|
||||
@@ -53,6 +53,22 @@ public:
|
||||
PostDelayedTaskImpl(std::move(task), delay, traits, location);
|
||||
}
|
||||
|
||||
inline void
|
||||
PostDelayedTaskWithPrecision(DelayPrecision precision,
|
||||
std::function<void()> &&task,
|
||||
TimeDelta delay,
|
||||
const Location &location = Location::Current())
|
||||
{
|
||||
switch (precision) {
|
||||
case DelayPrecision::kLow:
|
||||
PostDelayedTask(std::move(task), delay, location);
|
||||
break;
|
||||
case DelayPrecision::kHigh:
|
||||
PostDelayedHighPrecisionTask(std::move(task), delay, location);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static TaskQueueBase *Current();
|
||||
|
||||
bool IsCurrent() const { return Current() == this; };
|
||||
|
||||
54
include/sled/timer/task_queue_timeout.h
Normal file
54
include/sled/timer/task_queue_timeout.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
#ifndef SLED_TIMER_QUEUE_TIMEOUT_H
|
||||
#define SLED_TIMER_QUEUE_TIMEOUT_H
|
||||
|
||||
#include "sled/task_queue/task_queue_base.h"
|
||||
#include "sled/timer/timeout.h"
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
namespace sled {
|
||||
typedef uint64_t TimeMs;
|
||||
|
||||
class TaskQueueTimeoutFactory {
|
||||
public:
|
||||
TaskQueueTimeoutFactory(
|
||||
sled::TaskQueueBase &task_queue,
|
||||
std::function<TimeMs()> get_time,
|
||||
std::function<void(TimeoutID timeout_id)> on_expired)
|
||||
: task_queue_(task_queue),
|
||||
get_time_(get_time),
|
||||
on_expired_(on_expired)
|
||||
{}
|
||||
|
||||
std::unique_ptr<Timeout>
|
||||
CreateTimeout(sled::TaskQueueBase::DelayPrecision precision =
|
||||
sled::TaskQueueBase::DelayPrecision::kHigh)
|
||||
{
|
||||
return std::unique_ptr<TaskQueueTimeout>(
|
||||
new TaskQueueTimeout(*this, precision));
|
||||
}
|
||||
|
||||
private:
|
||||
class TaskQueueTimeout : public Timeout {
|
||||
public:
|
||||
TaskQueueTimeout(TaskQueueTimeoutFactory &parent,
|
||||
sled::TaskQueueBase::DelayPrecision precision);
|
||||
~TaskQueueTimeout() override;
|
||||
void Start(DurationMs duration, TimeoutID timeout_id) override;
|
||||
void Stop() override;
|
||||
|
||||
private:
|
||||
TaskQueueTimeoutFactory &parent_;
|
||||
const sled::TaskQueueBase::DelayPrecision precision_;
|
||||
TimeMs posted_task_expiration_ = std::numeric_limits<TimeMs>::max();
|
||||
TimeMs timeout_expiration_ = std::numeric_limits<TimeMs>::max();
|
||||
TimeoutID timeout_id_ = TimeoutID(0);
|
||||
};
|
||||
|
||||
sled::TaskQueueBase &task_queue_;
|
||||
const std::function<TimeMs()> get_time_;
|
||||
const std::function<void(TimeoutID)> on_expired_;
|
||||
};
|
||||
}// namespace sled
|
||||
#endif// SLED_TIMER_QUEUE_TIMEOUT_H
|
||||
25
include/sled/timer/timeout.h
Normal file
25
include/sled/timer/timeout.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#ifndef SLED_TIMER_TIMEOUT_H
|
||||
#define SLED_TIMER_TIMEOUT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace sled {
|
||||
typedef uint32_t DurationMs;
|
||||
typedef uint64_t TimeoutID;
|
||||
|
||||
class Timeout {
|
||||
public:
|
||||
virtual ~Timeout() = default;
|
||||
virtual void Start(DurationMs duration, TimeoutID timeout_id) = 0;
|
||||
virtual void Stop() = 0;
|
||||
|
||||
virtual void Restart(DurationMs duration, TimeoutID timeout_id)
|
||||
{
|
||||
Stop();
|
||||
Start(duration, timeout_id);
|
||||
}
|
||||
};
|
||||
}// namespace sled
|
||||
//
|
||||
#endif// SLED_TIMER_TIMEOUT_H
|
||||
75
include/sled/timer/timer.h
Normal file
75
include/sled/timer/timer.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#ifndef SLED_TIMER_TIMER_H
|
||||
#define SLED_TIMER_TIMER_H
|
||||
|
||||
#include "timeout.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sled/optional.h>
|
||||
#include <sled/task_queue/task_queue_base.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace sled {
|
||||
typedef uint64_t TimerID;
|
||||
typedef uint32_t TimerGeneration;
|
||||
|
||||
class Timer {
|
||||
public:
|
||||
using OnExpired = std::function<sled::optional<DurationMs>()>;
|
||||
Timer(const Timer &) = delete;
|
||||
Timer &operator=(const Timer &) = delete;
|
||||
~Timer();
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
void set_duration(DurationMs duration) { duration_ = duration; }
|
||||
|
||||
const DurationMs &duration() const { return duration_; }
|
||||
|
||||
int expiration_count() const { return expiration_count_; }
|
||||
|
||||
bool is_running() const { return is_running_; }
|
||||
|
||||
private:
|
||||
friend class TimerManager;
|
||||
using UnregisterHandler = std::function<void()>;
|
||||
Timer(TimerID id,
|
||||
const std::string &name,
|
||||
OnExpired on_expired,
|
||||
UnregisterHandler unregister_handler,
|
||||
std::unique_ptr<Timeout> timeout);
|
||||
void Trigger(TimerGeneration generation);
|
||||
|
||||
const TimerID id_;
|
||||
const std::string name_;
|
||||
const OnExpired on_expired_;
|
||||
const UnregisterHandler unregister_handler_;
|
||||
std::unique_ptr<Timeout> timeout_;
|
||||
|
||||
DurationMs duration_;
|
||||
|
||||
TimerGeneration generation_ = TimerGeneration(0);
|
||||
bool is_running_ = false;
|
||||
int expiration_count_ = 0;
|
||||
};
|
||||
|
||||
class TimerManager {
|
||||
using TimeoutCreator = std::function<std::unique_ptr<Timeout>(
|
||||
sled::TaskQueueBase::DelayPrecision)>;
|
||||
|
||||
public:
|
||||
explicit TimerManager(TimeoutCreator timeout_creator)
|
||||
: timeout_creator_(timeout_creator)
|
||||
{}
|
||||
|
||||
std::unique_ptr<Timer> CreateTimer(const std::string &name,
|
||||
Timer::OnExpired on_expired);
|
||||
void HandleTimeout(TimeoutID timeout_id);
|
||||
|
||||
private:
|
||||
const TimeoutCreator timeout_creator_;
|
||||
std::map<TimerID, Timer *> timers_;
|
||||
TimerID next_id_ = TimerID(0);
|
||||
};
|
||||
}// namespace sled
|
||||
#endif// SLED_TIMER_TIMER_H
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T = int64_t>
|
||||
constexpr T ns()
|
||||
constexpr T ns() const
|
||||
{
|
||||
return ToMultiple<1000, T>();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user