#pragma once // IPC utility // // created on 2022-11-29 // #include "referer.h" #include #include //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // object event // class linux_event : public refer { int32_t err_; sem_t local_sem_; sem_t* sem_; bool first_; bool multi_proc_; volatile bool waiting_; std::string desc_; std::string name_; static unsigned long to_abs_time_us; // used in sem_timedwait to calculate absolute time from elapse public: linux_event(const char* desc); // to initialize a in-process object linux_event(const char* name, const char* desc); // to initialize a multi-process object linux_event(sem_t* mem_sem, bool first/*invoke sem_init when true*/, const char* desc); // to initialize an event at given memory (shared memory) static int32_t clear_named_event(const char* name); static void reset_calc_abs_time(unsigned us = -1); // reset 'to_abs_time_us' value, -1 is for re-calc static bool abs_time_after(struct timespec* abstm, unsigned ms); protected: ~linux_event(); public: bool is_ready(void); bool is_named_first(void); // whether I created the named event bool wait_try(void); bool wait(unsigned timeout = WAIT_INFINITE/*ms*/); // WAIT_INFINITE is waiting unfinite, true when watied and false for wait timeout void trigger(void); void reset(void); // re-initialize. DANGEROUS !!! all wait operation before will not receive any event after this !!! bool is_waiting(void); }; template class safe_fifo { MUTEX lock_; std::deque que_; linux_event* wait_; public: safe_fifo() : wait_(new linux_event("fifo")) {} ~safe_fifo() { wait_->release(); } public: void save(const T& t, bool notify = false) { LOCKER lock(lock_); que_.push_back(std::move(t)); if (notify) wait_->trigger(); } bool take(T& t, bool wait = false) { if (wait) wait_->wait(); { LOCKER lock(lock_); if (que_.size()) { t = std::move(que_.front()); que_.pop_front(); return true; } else { return false; } } } size_t size(void) { LOCKER lock(lock_); return que_.size(); } void clear(void) { LOCKER lock(lock_); que_.clear(); } }; class shared_mem : public refer { std::string name_; int32_t id_; int32_t shm_id_; char* shm_buf_; size_t size_; bool first_; public: shared_mem(); static void init_page_info(void); static char* invalid_map_addr(void); static uint64_t mem_total_; static uint64_t page_unit_; static uint64_t huge_page_unit_; protected: ~shared_mem(); public: int32_t open(int32_t id, size_t* bytes, const char* name = nullptr); int32_t close(void); char* get_mem(size_t* size = nullptr); bool is_first(void); void clear_kernel_object(void); };