code_scanner/common/ipc_util.h

145 lines
3.3 KiB
C++

#pragma once
// IPC utility
//
// created on 2022-11-29
//
#include "referer.h"
#include <semaphore.h>
#include <deque>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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 T>
class safe_fifo
{
MUTEX lock_;
std::deque<T> 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);
};