Shared Memory¶
Shared memory transport for zero-copy inter-process frame passing.
-
namespace shmem¶
-
class SharedMemRingBuffer¶
- #include <sharedmemringbuffer.h>
Shared memory ring buffer synchronized with POSIX semaphores.
Multi-process ring buffer using multiple SharedMemSegments. Server pushes data, clients pull data with optional timeout. Handles overflow by zeroing semaphore and setting overflow flag.
Usage:
Server: Create with is_server=true, use push() to add data
Client: Create with is_server=false, use pull() to read data
Synchronization:
count_sem: Counts available items for reading
overflow_sem: Indicates buffer overflow occurred
// Server process SharedMemRingBuffer server_ring("my_buffer", 10, 1024, 0, true); if (!server_ring.init()) { // Handle initialization error return -1; } std::vector<uint8_t> data = {0x01, 0x02, 0x03, 0x04}; if (!server_ring.push(data)) { // Handle push error (buffer full, etc.) } // Client process SharedMemRingBuffer client_ring("my_buffer", 10, 1024, 5000, false); // 5s timeout if (!client_ring.init()) { // Handle initialization error return -1; } std::vector<uint8_t> received; if (client_ring.pull(received)) { // Process received data printf("Received %zu bytes\n", received.size()); } else { // Timeout or error occurred if (client_ring.isOverflow()) { printf("Buffer overflow detected\n"); } }
- Param name:
Unique identifier for the shared memory buffer
- Param n_cells:
Number of ring buffer cells
- Param cell_size:
Maximum size per cell in bytes
- Param timeout_ms:
Client timeout in milliseconds (0 = no timeout)
- Param is_server:
true for server (creates buffer), false for client
Public Functions
-
SharedMemRingBuffer(const std::string &name, int n_cells, size_t cell_size, int timeout_ms = 0, bool is_server = false)¶
Constructor.
- Parameters:
name – Unique identifier for the ring buffer
n_cells – Number of cells in the ring buffer
cell_size – Maximum size of each cell in bytes
timeout_ms – Semaphore timeout in milliseconds (0 = wait forever)
is_server – true for server (creates resources), false for client
-
~SharedMemRingBuffer()¶
Destructor - cleans up semaphores and segments.
-
void init()¶
Initialize the ring buffer.
Must be called after construction. Creates/opens semaphores and segments.
- Throws:
std::runtime_error – if initialization fails
-
void close()¶
Clean up ring buffer resources.
Must be called before destruction. Closes semaphores and segments.
-
bool push(const std::vector<uint8_t> &data)¶
Push data into the ring buffer (server side)
If buffer is full, zeros the semaphore and sets overflow flag.
- Parameters:
data – Data to push into the buffer
- Throws:
std::runtime_error – if not in server mode or other error
- Returns:
true if successful
-
bool push(const uint8_t *buffer, size_t size)¶
Push data using direct buffer access (server side)
Zero-copy version for serialized frames.
- Parameters:
buffer – Pointer to data buffer
size – Size of data in bytes
- Returns:
true if successful
-
size_t push(size_t (*frame_serialize_func)(uint8_t*, size_t, Limef::frame::Frame*), Limef::frame::Frame *frame)¶
Push data using direct buffer access (server side)
Give a frame serialization function that writes directly to the correct shmem buffer Function arguments:
the logic: give a callback function that serializes frame data into the desired memory address (that only the sharedmemringbuffe knows)
- Parameters:
pointer – to function that takes bytebuffer address and size
pointer – to frame
- Returns:
returns number of overflown bytes. If all data was written ok, return 0.
-
bool pull(std::vector<uint8_t> &data)¶
Pull data from the ring buffer (client side)
Blocks until data is available or timeout occurs.
- Parameters:
data – Vector to receive the data
- Throws:
std::runtime_error – if not in client mode or other error
- Returns:
true if data received, false if timeout
-
bool pull(const uint8_t *&buffer, size_t &size)¶
Pull data using direct buffer access (client side)
Zero-copy version for deserialized frames.
- Parameters:
buffer – Pointer to receive data pointer (read-only)
size – Reference to receive data size
- Returns:
true if data received, false if timeout
-
bool isReady() const¶
Check if ring buffer is ready for use.
- Returns:
true if all segments are properly initialized
-
int getValue() const¶
Get current semaphore value (available items)
- Returns:
int Number of items available for reading
-
bool isOverflow() const¶
Check if overflow flag is set.
- Returns:
true if buffer overflow occurred
-
void clearOverflow()¶
Clear the overflow flag.
-
void serverUseFd(EventFd &event_fd)¶
Enable eventfd for server-side signaling (call once after construction)
Registers an eventfd that will be written to (counter += 1) after every successful push(). Call this before the first push().
- Parameters:
event_fd – EventFd instance to use for signaling
-
void clientUseFd(EventFd &event_fd)¶
Enable eventfd for client-side polling (call once after construction)
Registers the same eventfd so that pull() can drain it when the queue empties. The caller can then use select/poll on the fd to multiplex several ring buffers or other I/O sources.
- Parameters:
event_fd – EventFd instance to use for polling
-
class SharedMemSegment¶
- #include <sharedmemsegment.h>
Simple shared memory segment for serialized frame data.
Manages a POSIX shared memory segment with a size header followed by data. Layout: [size_t data_size][uint8_t data[max_size]]
Usage:
Server process: Create with is_server=true, use getWritePtr() + commitWrite()
Client process: Create with is_server=false, use getReadPtr() + getDataSize()
Public Functions
-
SharedMemSegment(const std::string &name, size_t max_size, bool is_server = false)¶
Constructor.
- Parameters:
name – Unique identifier for the shared memory segment
max_size – Maximum size in bytes for the data payload (not including size header)
is_server – true for server (creates shmem), false for client (attaches to existing)
-
~SharedMemSegment()¶
Destructor - cleans up shared memory resources.
-
void init()¶
Initialize the shared memory segment.
Must be called after construction. For servers, creates and maps the segment. For clients, attempts to attach to existing segment.
- Throws:
std::runtime_error – if initialization fails
-
void close()¶
Clean up shared memory resources.
Must be called before destruction. Unmaps memory and (for servers) unlinks segment.
-
uint8_t *getWritePtr()¶
Get pointer for writing data (server side)
- Returns:
uint8_t* Pointer to data area where serialized frame can be written
-
inline size_t getMaxSize() const¶
Get maximum available space for data.
- Returns:
size_t Maximum bytes that can be written via getWritePtr()
-
void commitWrite(size_t actual_size)¶
Commit written data (server side)
Updates the internal size variable to now how much data the current buffer actually has
- Parameters:
actual_size – Number of bytes actually written to the buffer
-
const uint8_t *getReadPtr() const¶
Get pointer for reading data (client side)
- Returns:
const uint8_t* Pointer to data area containing serialized frame
-
size_t getDataSize() const¶
Get size of available data (client side)
- Returns:
size_t Number of bytes available for reading
-
bool put(const std::vector<uint8_t> &data)¶
Copy data into shared memory (server side)
- Parameters:
data – Vector containing data to copy
- Throws:
std::runtime_error – if data too large or other error
- Returns:
true if successful
-
bool get(std::vector<uint8_t> &data)¶
Copy data from shared memory (client side)
- Parameters:
data – Vector to receive copied data
- Returns:
true if successful
-
inline bool isReady() const¶
Check if shared memory is ready for use.
- Returns:
true if segment is properly initialized and accessible
-
class ShmemClient¶
- #include <shmem_client.h>
Unified shared memory client — pulls any supported frame type.
Connects to a shared memory ring buffer created by ShmemServerFrameFilter and deserializes frames. The server writes a 1-byte FrameClass tag before every payload; pull() reads that tag and dispatches to the right internal frame object, returning a Frame* base pointer.
Caller downcasts with frame->as<DecodedFrame>() or frame->as<RawFrame>(). The returned pointer is valid until the next pull() call.
Usage:
EventFd event_fd; ShmemRingbufferContext ctx("myring", 5, 8*1024*1024, 100, event_fd); ShmemClient client(ctx); struct pollfd pfd = { event_fd.getFd(), POLLIN, 0 }; while (poll(&pfd, 1, timeout_ms) > 0) { Limef::frame::Frame* frame = client.pull(); if (auto* df = frame->as<Limef::frame::DecodedFrame>()) { // decoded video or audio } else if (auto* rf = frame->as<Limef::frame::RawFrame>()) { // raw bytes } }
Public Functions
-
Limef::frame::Frame *pull()¶
Pull next frame from shared memory.
Reads the 1-byte FrameClass tag written by the server, then deserializes the payload into the matching internal frame object.
Returns a pointer to an internal frame that is reused on each call — copy the data if you need it to survive the next pull().
- Throws:
std::runtime_error – on timeout, unknown type tag, or deserialization failure
- Returns:
Limef::frame::Frame* Pointer to internal DecodedFrame, RawFrame, or StreamFrame
-
Limef::frame::Frame *pull()¶
-
struct ShmemRingbufferContext¶
- #include <sharedmemringbuffer.h>
Context for shared memory communication.
-
class SharedMemRingBuffer¶