/* * ===================================================================================== * * Filename: msg.h * * Description: * * Version: 1.0 * Created: 2021年03月24日 16时49分20秒 * Revision: none * Compiler: gcc * * Author: Li Chao (), * Organization: * * ===================================================================================== */ #ifndef MSG_5BILLZET #define MSG_5BILLZET #include #include "shm.h" #include #include namespace bhome_shm { // msg is safe to be stored in shared memory, so POD data or offset_ptr is required. // message format: header(meta) + body(data). enum MsgType { kMsgTypeNull = 0, kMsgTypeNormal = 1, kMsgTypeMaxValue }; typedef boost::uuids::uuid MQId; const uint32_t kMsgMetaTag = 0xf1e2d3c4; struct MsgMetaV1 { uint16_t self_size_ = sizeof(MsgMetaV1); // sizeof(*this) uint16_t type_ = kMsgTypeNormal; // msg type. uint32_t tag_ = kMsgMetaTag; uint32_t data_size_ = 0; MQId src_id_; // more fields add at end, must not change MsgMetaV1():src_id_(boost::uuids::nil_uuid()){} bool Parse(const void *p); void Pack(void *p); }; // store ref count, msgs shareing the same data should also hold a pointer of the same RefCount object. class RefCount : private boost::noncopyable { public: int Inc() { Guard lk(mutex_); return ++num_; } int Dec() { Guard lk(mutex_); return --num_; } int Get() { Guard lk(mutex_); return num_; } private: Mutex mutex_; int num_ = 1; }; class Msg { private: offset_ptr ptr_; offset_ptr count_; public: Msg(void *p=0, RefCount *c=0):ptr_(p), count_(c) {} void swap(Msg &a) { std::swap(ptr_, a.ptr_); std::swap(count_, a.count_); } // ~Msg() { RemoveRef(); } // Msg(const Msg &a):ptr_(a.ptr_), count_(a.count_) { AddRef(); } // Msg(Msg &&a):ptr_(a.ptr_), count_(a.count_) { a.ptr_ = 0; a.count_ = 0; } // Msg & operator = (const Msg &a) { Msg(a).swap(*this); } // Msg & operator = (Msg &&a) { Msg(std::move(a)).swap(*this); } template T *get() { return static_cast(ptr_.get()); } int AddRef() const { return IsCounted() ? count_->Inc() : 1; } int RemoveRef() const{ return IsCounted() ? count_->Dec() : 0; } int Count() const{ return IsCounted() ? count_->Get() : 1; } bool IsCounted() const { return static_cast(count_); } bool Build(SharedMemory &shm, const MQId &src_id, const void *p, const size_t size, const bool refcount); void FreeFrom(SharedMemory &shm); }; inline void swap(Msg &m1, Msg &m2) { m1.swap(m2); } } // namespace bhome_shm #endif // end of include guard: MSG_5BILLZET