2020-12-13 09:15:45 +00:00
|
|
|
#ifndef SHMEMQ_INCLUDED
|
|
|
|
#define SHMEMQ_INCLUDED 1
|
|
|
|
|
2020-12-15 15:01:30 +00:00
|
|
|
#include <semaphore.h>
|
2020-12-13 09:48:40 +00:00
|
|
|
#include <stdbool.h>
|
2020-12-13 09:15:45 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
|
2020-12-15 07:22:52 +00:00
|
|
|
#define SHMEMQ_DELETE(shmemq, error_ptr) { \
|
|
|
|
shmemq_delete(shmemq, error_ptr); \
|
|
|
|
shmemq = NULL; \
|
|
|
|
}
|
|
|
|
|
2020-12-13 09:44:03 +00:00
|
|
|
#define SHMEMQ_NAME_SIZE_MAX ((size_t)255)
|
2020-12-13 11:25:53 +00:00
|
|
|
#define SHMEMQ_NAME_SLEN_MAX (SHMEMQ_NAME_SIZE_MAX - 1)
|
2020-12-13 09:44:03 +00:00
|
|
|
|
2020-12-13 15:45:07 +00:00
|
|
|
// TODO: Resize buffer dynamically.
|
|
|
|
// #define SHMEMQ_BUFFER_SIZE_MIN (sizeof(struct Shmemq_BufferHeader))
|
2020-12-13 17:39:02 +00:00
|
|
|
#define SHMEMQ_BUFFER_SIZE_MIN (sizeof(struct ShmemqBufferHeader) + 800)
|
2020-12-13 12:19:46 +00:00
|
|
|
|
2020-12-14 11:27:39 +00:00
|
|
|
#define SHMEMQ_FRAME_SIZE ((size_t)16)
|
2020-12-13 09:15:45 +00:00
|
|
|
|
|
|
|
#define SHMEMQ_FRAME_DATA_SIZE \
|
2020-12-13 17:39:02 +00:00
|
|
|
(SHMEMQ_FRAME_SIZE - sizeof(struct ShmemqFrameHeader))
|
2020-12-13 09:15:45 +00:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2020-12-13 17:41:32 +00:00
|
|
|
typedef enum ShmemqError {
|
2020-12-13 11:08:52 +00:00
|
|
|
SHMEMQ_ERROR_NONE = 0,
|
2020-12-13 12:17:47 +00:00
|
|
|
|
2020-12-14 16:01:08 +00:00
|
|
|
// Invalid values.
|
2020-12-13 12:17:47 +00:00
|
|
|
SHMEMQ_ERROR_INVALID_NAME = 1,
|
|
|
|
|
2020-12-14 16:01:08 +00:00
|
|
|
// Bugs in user code.
|
2020-12-14 15:59:52 +00:00
|
|
|
SHMEMQ_ERROR_BUG_POP_END_ON_EMPTY_QUEUE = 50,
|
2020-12-14 18:11:08 +00:00
|
|
|
SHMEMQ_ERROR_BUG_PUSH_END_ON_FULL_QUEUE = 51,
|
2020-12-15 07:09:04 +00:00
|
|
|
SHMEMQ_ERROR_BUG_PUSH_END_OVERFLOW = 52,
|
2020-12-14 15:59:52 +00:00
|
|
|
|
2020-12-14 16:01:08 +00:00
|
|
|
// Failed system calls.
|
|
|
|
SHMEMQ_ERROR_FAILED_MALLOC = 100,
|
|
|
|
SHMEMQ_ERROR_FAILED_SHM_OPEN = 101,
|
|
|
|
SHMEMQ_ERROR_FAILED_FTRUNCATE = 102,
|
|
|
|
SHMEMQ_ERROR_FAILED_MMAP = 103,
|
|
|
|
SHMEMQ_ERROR_FAILED_MUNMAP = 104,
|
|
|
|
SHMEMQ_ERROR_FAILED_CLOSE = 105,
|
|
|
|
SHMEMQ_ERROR_FAILED_SHM_UNLINK = 106,
|
2020-12-15 15:01:30 +00:00
|
|
|
SHMEMQ_ERROR_FAILED_SEM_INIT = 107,
|
2020-12-13 17:41:32 +00:00
|
|
|
} ShmemqError;
|
2020-12-13 11:08:52 +00:00
|
|
|
|
2020-12-13 17:39:02 +00:00
|
|
|
struct ShmemqFrameHeader {
|
2020-12-13 18:32:03 +00:00
|
|
|
size_t message_frames_count;
|
2020-12-13 09:15:45 +00:00
|
|
|
};
|
|
|
|
|
2020-12-13 18:05:05 +00:00
|
|
|
typedef struct ShmemqFrame {
|
2020-12-13 17:39:02 +00:00
|
|
|
struct ShmemqFrameHeader header;
|
2020-12-13 09:15:45 +00:00
|
|
|
unsigned char data[SHMEMQ_FRAME_DATA_SIZE];
|
2020-12-13 18:05:05 +00:00
|
|
|
} *ShmemqFrame;
|
2020-12-13 09:15:45 +00:00
|
|
|
|
2020-12-13 17:39:02 +00:00
|
|
|
struct ShmemqBufferHeader {
|
2020-12-13 14:56:14 +00:00
|
|
|
bool is_ready;
|
2020-12-13 09:15:45 +00:00
|
|
|
size_t frames_count;
|
|
|
|
size_t read_frame_index;
|
|
|
|
size_t write_frame_index;
|
2020-12-15 15:01:30 +00:00
|
|
|
sem_t read_sem;
|
|
|
|
sem_t write_sem;
|
2020-12-13 09:15:45 +00:00
|
|
|
};
|
|
|
|
|
2020-12-13 17:39:02 +00:00
|
|
|
struct ShmemqBuffer {
|
|
|
|
struct ShmemqBufferHeader header;
|
|
|
|
struct ShmemqFrame frames[];
|
2020-12-13 09:15:45 +00:00
|
|
|
};
|
|
|
|
|
2020-12-13 15:04:20 +00:00
|
|
|
typedef struct Shmemq {
|
2020-12-13 09:44:03 +00:00
|
|
|
char name[SHMEMQ_NAME_SIZE_MAX];
|
2020-12-13 09:48:40 +00:00
|
|
|
bool is_consumer;
|
2020-12-13 11:32:17 +00:00
|
|
|
int shm_id;
|
2020-12-13 17:39:02 +00:00
|
|
|
struct ShmemqBuffer *buffer;
|
2020-12-13 15:04:20 +00:00
|
|
|
} *Shmemq;
|
2020-12-13 09:44:03 +00:00
|
|
|
|
2021-08-17 09:14:01 +00:00
|
|
|
const char *shmemq_error_str(ShmemqError error);
|
|
|
|
|
2020-12-13 17:54:07 +00:00
|
|
|
Shmemq shmemq_new(const char *name, bool is_consumer, ShmemqError *error_ptr);
|
2020-12-13 12:52:10 +00:00
|
|
|
|
2020-12-13 17:33:08 +00:00
|
|
|
void shmemq_init(
|
2020-12-13 15:51:28 +00:00
|
|
|
Shmemq shmemq,
|
2020-12-13 12:52:10 +00:00
|
|
|
const char *name,
|
2020-12-13 17:33:08 +00:00
|
|
|
bool is_consumer,
|
2020-12-13 17:41:32 +00:00
|
|
|
ShmemqError *error_ptr
|
2020-12-13 12:52:10 +00:00
|
|
|
);
|
2020-12-13 11:08:52 +00:00
|
|
|
|
2020-12-13 17:41:32 +00:00
|
|
|
void shmemq_delete(Shmemq shmemq, ShmemqError *error_ptr);
|
2020-12-13 13:41:44 +00:00
|
|
|
|
2020-12-13 17:41:32 +00:00
|
|
|
void shmemq_finish(Shmemq shmemq, ShmemqError *error_ptr);
|
2020-12-13 13:41:44 +00:00
|
|
|
|
2020-12-13 18:05:05 +00:00
|
|
|
ShmemqFrame shmemq_push_start(Shmemq shmemq);
|
|
|
|
|
2020-12-14 11:51:56 +00:00
|
|
|
void shmemq_push_end(Shmemq shmemq, size_t data_size, ShmemqError *error_ptr);
|
2020-12-13 18:11:34 +00:00
|
|
|
|
2020-12-14 15:59:52 +00:00
|
|
|
ShmemqFrame shmemq_pop_start(Shmemq shmemq);
|
|
|
|
|
|
|
|
void shmemq_pop_end(Shmemq shmemq, ShmemqError *error_ptr);
|
|
|
|
|
2020-12-13 09:15:45 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|