#pragma once // Objects for Inter-Process-Communication // // created on 2022-03-01 // #if defined(WIN32) || defined(_WIN64) #include #define sem_t HANDLE #define USB_TIMEOUT_INFINITE -1 #else #include #include #include #include #define USB_TIMEOUT_INFINITE 0 #endif #include #include #include #include //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 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 lock(mutex_); return ++ref_; } int release(void) { int ref = 0; { std::lock_guard lock(mutex_); ref = --ref_; } if (ref == 0) delete this; return ref; } }; template 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; int statu; // SANE_Image_Statu unsigned bytes; uint32_t src_id; }IMH; typedef struct _img { IMH header; unsigned offset; std::shared_ptr data; }IMGDT; class final_img_queue { mutable std::mutex lock_; std::vector 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, int statu , 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); };