145 lines
3.3 KiB
C++
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);
|
|
};
|
|
|