code_util/hg_ipc.h

244 lines
5.6 KiB
C
Raw Permalink Normal View History

2023-02-24 09:24:48 +00:00
#pragma once
// Objects for Inter-Process-Communication
//
// created on 2022-03-01
//
#if defined(WIN32) || defined(_WIN64)
#include <Windows.h>
#define sem_t HANDLE
#define USB_TIMEOUT_INFINITE -1
#else
#include <semaphore.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#define USB_TIMEOUT_INFINITE 0
#endif
#include <string>
#include <vector>
#include <mutex>
#include <memory>
#include "base.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// memory management ...
void* allocate_memory(size_t bytes, const char* log_msg = "");
void free_memory(void* ptr);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class platform_event
{
sem_t sem_;
volatile bool waiting_;
std::string dbg_info_;
public:
platform_event();
~platform_event();
public:
bool try_wait(void);
bool wait(unsigned timeout = USB_TIMEOUT_INFINITE/*ms*/); // USB_TIMEOUT_INFINITE is waiting unfinite, true when watied and false for wait timeout
void notify(void);
bool is_waiting(void);
void set_debug_info(const char* info);
};
// class refer
// {
// volatile int ref_;
// std::mutex mutex_;
// protected:
// refer() : ref_(1)
// {}
// virtual ~refer()
// {}
// public:
// int add_ref(void)
// {
// std::lock_guard<std::mutex> lock(mutex_);
// return ++ref_;
// }
// int release(void)
// {
// int ref = 0;
// {
// std::lock_guard<std::mutex> lock(mutex_);
// ref = --ref_;
// }
// if (ref == 0)
// delete this;
// return ref;
// }
// };
template<class T>
class do_when_born_and_dead : public refer
{
T* obj_;
void(T::* dead_)(void*);
void* param_;
public:
do_when_born_and_dead(T* obj, void(T::* born)(void*), void(T::* dead)(void*), void* param)
: obj_(obj), dead_(dead), param_(param)
{
if(born)
(obj_->*born)(param_);
}
protected:
~do_when_born_and_dead()
{
(obj_->*dead_)(param_);
}
};
// mutex object
class shared_memory : public refer
{
unsigned long long key_;
void* obj_;
bool first_;
size_t bytes_;
size_t len_;
void init(void);
void clear(void);
char* get_buf(void);
void release_buf(void* buf);
#if !defined(WIN32) && !defined(_WIN64)
static std::string get_proc_name_by_pid(pid_t pid);
#endif
public:
shared_memory(unsigned long long key, size_t size = 1024);
protected:
~shared_memory();
public:
bool is_ok(void);
bool is_first(void);
std::string read(void);
int write(const char* data, size_t len);
};
// buffer
#if defined(WIN32) || defined(_WIN64)
#define HANDLE_NAME HANDLE
#define INVALID_HANDLE_NAME NULL
#else
#define HANDLE_NAME int
#define INVALID_HANDLE_NAME -1
#endif
class tiny_file_map
{
unsigned int size_;
unsigned int page_size_;
HANDLE_NAME map_;
unsigned char *buf_;
std::string file_;
bool keep_f_;
unsigned int map_off_;
unsigned int map_bytes_;
int map_to_mem(unsigned int off = 0);
public:
tiny_file_map();
~tiny_file_map();
static HANDLE_NAME open_file_for_mapping(const char* file, unsigned* bytes, bool create);
static void close_handle_name(HANDLE_NAME h);
static void* sys_map_api(HANDLE_NAME h, int access, unsigned int off, unsigned size, int* err);
static void sys_unmap_api(void* buf, size_t size = 0);
public:
int open(const char* file, bool existing = true, unsigned int size = 0);
void close(void);
void keep_file(bool keep);
unsigned char* mapping_buffer(unsigned int off, unsigned int* bytes);
std::string file(void);
unsigned int size(void);
// mapping if unmapped; or unmapping if mapped
bool swap(void);
};
class tiny_buffer
{
unsigned int size_;
unsigned char *buf_;
tiny_file_map fmap_;
int img_statu_;
void init(const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id);
public:
tiny_buffer(unsigned int size, const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id);
tiny_buffer(const char* src_file);
~tiny_buffer();
public:
unsigned int size(void);
unsigned char* data(unsigned int off, unsigned int* bytes/*[in] - need bytes, [out] - real bytes*/);
void keep_file(bool keep);
std::string file(void);
// mapping if unmapped; or unmapping if mapped
bool swap(void);
int to_file(const char* file);
void set_image_statu(int statu);
int get_image_statu(void);
};
typedef struct _img_header
{
int width;
int height;
int bits;
int channels;
int line_bytes;
unsigned bytes;
uint32_t src_id;
}IMH;
typedef struct _img
{
IMH header;
unsigned offset;
std::shared_ptr<tiny_buffer> data;
}IMGDT;
class final_img_queue
{
mutable std::mutex lock_;
std::vector<IMGDT> queue_;
long long mem_usage_;
public:
final_img_queue();
~final_img_queue();
public:
unsigned long long mem_usage(void);
size_t size(void);
void clear(void);
bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes
, const char* tmp_path, const char* name_leading, const char* ext, int ind, uint32_t id);
bool front(IMH* header);
void fetch_front(void* buf, int* len, bool* over);
};