From cf05ea3d9f43e4e84d621e1f9d54cbef552b6e2b Mon Sep 17 00:00:00 2001 From: lichao <lichao@aiotlink.com> Date: 星期二, 18 五月 2021 16:53:28 +0800 Subject: [PATCH] fix center init mutex. --- src/bh_util.h | 73 +++++++++++++++++++++++++++++++++--- 1 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/bh_util.h b/src/bh_util.h index b5dc45e..15ffeb0 100644 --- a/src/bh_util.h +++ b/src/bh_util.h @@ -18,7 +18,9 @@ #ifndef BH_UTIL_SOXWOK67 #define BH_UTIL_SOXWOK67 +#include "macro.h" #include <functional> +#include <mutex> #include <stdint.h> inline uint16_t Get8(const void *p) @@ -90,6 +92,8 @@ inline void PutInt(void *p, uint32_t u) { Put32(p, u); } inline void PutInt(void *p, uint64_t u) { Put64(p, u); } +constexpr uint64_t MaskBits(int nbits) { return (uint64_t(1) << nbits) - 1; } + class ExitCall { typedef std::function<void(void)> func_t; @@ -104,12 +108,67 @@ } }; -// macro helper -#define JOIN_IMPL(a, b) a##b -#define JOIN(a, b) JOIN_IMPL(a, b) -// defer function / lambda. -#define DEFERF(func) ExitCall JOIN(defer_, __LINE__)(func) -// defer simple expression -#define DEFER1(expr) DEFERF([&]() { expr; }) +template <class D, class M, class G = std::unique_lock<M>> +class SyncedPtr +{ + G lock_; + D *p_ = nullptr; + +public: + SyncedPtr(M &mtx, D &data) : + lock_(mtx), p_(&data) {} + SyncedPtr(SyncedPtr &&a) + { + lock_.swap(a.lock_); + std::swap(p_, a.p_); + } + D *operator->() const { return p_; } + D &operator*() const { return *p_; } +}; + +template <class T, class TMutex = std::mutex, class Lock = std::unique_lock<TMutex>> +class Synced +{ + typedef T Data; + TMutex mutex_; + Data data_; + typedef SyncedPtr<Data, TMutex, Lock> Ptr; + +public: + template <class... P> + explicit Synced(const P &...p) : + data_(p...) {} + Ptr operator->() { return Ptr(mutex_, data_); } + auto Apply(const auto &f) + { + Lock lk(mutex_); + return f(data_); + } +}; + +template <class T, class Tag> +class StaticDataRef +{ + typedef T *Ptr; + static inline Ptr &ptr() + { + static Ptr sp(nullptr); + return sp; + } + +protected: + static inline T &GetData(const std::string &msg = "Must set data before use!") + { + if (!ptr()) { throw std::logic_error(msg); } + return *ptr(); + } + +public: + static bool SetData(T &t) + { + auto Bind = [&]() { ptr() = &t; return true; }; + return ptr() ? false : Bind(); + } +}; #endif /* end of include guard: BH_UTIL_SOXWOK67 */ -- Gitblit v1.8.0