libwebsockets
Lightweight C library for HTML5 websockets
|
Macros | |
#define | lws_ring_consume_and_update_oldest_tail(___ring, ___type, ___ptail, ___count, ___list_head, ___mtail, ___mlist) |
#define | lws_ring_consume_single_tail(___ring, ___ptail, ___count) |
Functions | |
LWS_VISIBLE LWS_EXTERN struct lws_ring * | lws_ring_create (size_t element_len, size_t count, void(*destroy_element)(void *element)) |
LWS_VISIBLE LWS_EXTERN void | lws_ring_destroy (struct lws_ring *ring) |
LWS_VISIBLE LWS_EXTERN size_t | lws_ring_get_count_free_elements (struct lws_ring *ring) |
LWS_VISIBLE LWS_EXTERN size_t | lws_ring_get_count_waiting_elements (struct lws_ring *ring, uint32_t *tail) |
LWS_VISIBLE LWS_EXTERN size_t | lws_ring_insert (struct lws_ring *ring, const void *src, size_t max_count) |
LWS_VISIBLE LWS_EXTERN size_t | lws_ring_consume (struct lws_ring *ring, uint32_t *tail, void *dest, size_t max_count) |
LWS_VISIBLE LWS_EXTERN const void * | lws_ring_get_element (struct lws_ring *ring, uint32_t *tail) |
LWS_VISIBLE LWS_EXTERN void | lws_ring_update_oldest_tail (struct lws_ring *ring, uint32_t tail) |
LWS_VISIBLE LWS_EXTERN uint32_t | lws_ring_get_oldest_tail (struct lws_ring *ring) |
LWS_VISIBLE LWS_EXTERN int | lws_ring_next_linear_insert_range (struct lws_ring *ring, void **start, size_t *bytes) |
LWS_VISIBLE LWS_EXTERN void | lws_ring_bump_head (struct lws_ring *ring, size_t bytes) |
LWS_VISIBLE LWS_EXTERN void | lws_ring_dump (struct lws_ring *ring, uint32_t *tail) |
Provides an abstract ringbuffer api supporting one head and one or an unlimited number of tails.
All of the members are opaque and manipulated by lws_ring_...() apis.
The lws_ring and its buffer is allocated at runtime on the heap, using
It may contain any type, the size of the "element" stored in the ring buffer and the number of elements is given at creation time.
When you create the ringbuffer, you can optionally provide an element destroy callback that frees any allocations inside the element. This is then automatically called for elements with no tail behind them, ie, elements which don't have any pending consumer are auto-freed.
Whole elements may be inserted into the ringbuffer and removed from it, using
You can find out how many whole elements are free or waiting using
In addition there are special purpose optional byte-centric apis
which let you, eg, read() directly into the ringbuffer without needing an intermediate bounce buffer.
The accessors understand that the ring wraps, and optimizes insertion and consumption into one or two memcpy()s depending on if the head or tail wraps.
lws_ring only supports a single head, but optionally multiple tails with an API to inform it when the "oldest" tail has moved on. You can give NULL where-ever an api asks for a tail pointer, and it will use an internal single tail pointer for convenience.
The "oldest tail", which is the only tail if you give it NULL instead of some other tail, is used to track which elements in the ringbuffer are still unread by anyone.
#define lws_ring_consume_and_update_oldest_tail | ( | ___ring, | |
___type, | |||
___ptail, | |||
___count, | |||
___list_head, | |||
___mtail, | |||
___mlist | |||
) |
#include <include/libwebsockets/lws-ring.h>
#define lws_ring_consume_single_tail | ( | ___ring, | |
___ptail, | |||
___count | |||
) |
#include <include/libwebsockets/lws-ring.h>
LWS_VISIBLE LWS_EXTERN void lws_ring_bump_head | ( | struct lws_ring * | ring, |
size_t | bytes | ||
) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_bump_head(): used to write directly into the ring
ring | the struct lws_ring to operate on |
bytes | the number of bytes you inserted at the current head |
LWS_VISIBLE LWS_EXTERN size_t lws_ring_consume | ( | struct lws_ring * | ring, |
uint32_t * | tail, | ||
void * | dest, | ||
size_t | max_count | ||
) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_consume(): attempt to copy out and remove up to max_count elements to src
ring | the struct lws_ring to report on |
tail | a pointer to the tail struct to use, or NULL for single tail |
dest | the array of elements to be inserted. or NULL for no copy |
max_count | the number of available elements at src |
Attempts to copy out as many waiting elements as possible into dest, from the perspective of the given tail, up to max_count. If dest is NULL, the copying out is not done but the elements are logically consumed as usual. NULL dest is useful in combination with lws_ring_get_element(), where you can use the element direct from the ringbuffer and then call this with NULL dest to logically consume it.
Increments the tail position according to how many elements could be consumed.
Returns the number of elements consumed.
LWS_VISIBLE LWS_EXTERN struct lws_ring* lws_ring_create | ( | size_t | element_len, |
size_t | count, | ||
void(*)(void *element) | destroy_element | ||
) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_create(): create a new ringbuffer
element_len | the size in bytes of one element in the ringbuffer |
count | the number of elements the ringbuffer can contain |
destroy_element | NULL, or callback to be called for each element that is removed from the ringbuffer due to the oldest tail moving beyond it |
Creates the ringbuffer and allocates the storage. Returns the new lws_ring *, or NULL if the allocation failed.
If non-NULL, destroy_element will get called back for every element that is retired from the ringbuffer after the oldest tail has gone past it, and for any element still left in the ringbuffer when it is destroyed. It replaces all other element destruction code in your user code.
LWS_VISIBLE LWS_EXTERN void lws_ring_destroy | ( | struct lws_ring * | ring | ) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_destroy(): destroy a previously created ringbuffer
ring | the struct lws_ring to destroy |
Destroys the ringbuffer allocation and the struct lws_ring itself.
LWS_VISIBLE LWS_EXTERN size_t lws_ring_get_count_free_elements | ( | struct lws_ring * | ring | ) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_get_count_free_elements(): return how many elements can fit in the free space
ring | the struct lws_ring to report on |
Returns how much room is left in the ringbuffer for whole element insertion.
LWS_VISIBLE LWS_EXTERN size_t lws_ring_get_count_waiting_elements | ( | struct lws_ring * | ring, |
uint32_t * | tail | ||
) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_get_count_waiting_elements(): return how many elements can be consumed
ring | the struct lws_ring to report on |
tail | a pointer to the tail struct to use, or NULL for single tail |
Returns how many elements are waiting to be consumed from the perspective of the tail pointer given.
LWS_VISIBLE LWS_EXTERN const void* lws_ring_get_element | ( | struct lws_ring * | ring, |
uint32_t * | tail | ||
) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_get_element(): get a pointer to the next waiting element for tail
ring | the struct lws_ring to report on |
tail | a pointer to the tail struct to use, or NULL for single tail |
Points to the next element that tail would consume, directly in the ringbuffer. This lets you write() or otherwise use the element without having to copy it out somewhere first.
After calling this, you must call lws_ring_consume(ring, &tail, NULL, 1) which will logically consume the element you used up and increment your tail (tail may also be NULL there if you use a single tail).
Returns NULL if no waiting element, or a const void * pointing to it.
LWS_VISIBLE LWS_EXTERN uint32_t lws_ring_get_oldest_tail | ( | struct lws_ring * | ring | ) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_get_oldest_tail(): get current oldest available data index
ring | the struct lws_ring to report on |
If you are initializing a new ringbuffer consumer, you can set its tail to this to start it from the oldest ringbuffer entry still available.
LWS_VISIBLE LWS_EXTERN size_t lws_ring_insert | ( | struct lws_ring * | ring, |
const void * | src, | ||
size_t | max_count | ||
) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_insert(): attempt to insert up to max_count elements from src
ring | the struct lws_ring to report on |
src | the array of elements to be inserted |
max_count | the number of available elements at src |
Attempts to insert as many of the elements at src as possible, up to the maximum max_count. Returns the number of elements actually inserted.
LWS_VISIBLE LWS_EXTERN int lws_ring_next_linear_insert_range | ( | struct lws_ring * | ring, |
void ** | start, | ||
size_t * | bytes | ||
) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_next_linear_insert_range(): used to write directly into the ring
ring | the struct lws_ring to report on |
start | pointer to a void * set to the start of the next ringbuffer area |
bytes | pointer to a size_t set to the max length you may use from *start |
This provides a low-level, bytewise access directly into the ringbuffer allowing direct insertion of data without having to use a bounce buffer.
The api reports the position and length of the next linear range that can be written in the ringbuffer, ie, up to the point it would wrap, and sets *start and *bytes accordingly. You can then, eg, directly read() into *start for up to *bytes, and use lws_ring_bump_head() to update the lws_ring with what you have done.
Returns nonzero if no insertion is currently possible.
LWS_VISIBLE LWS_EXTERN void lws_ring_update_oldest_tail | ( | struct lws_ring * | ring, |
uint32_t | tail | ||
) |
#include <include/libwebsockets/lws-ring.h>
lws_ring_update_oldest_tail(): free up elements older than tail for reuse
ring | the struct lws_ring to report on |
tail | a pointer to the tail struct to use, or NULL for single tail |
If you are using multiple tails, you must use this API to inform the lws_ring when none of the tails still need elements in the fifo any more, by updating it when the "oldest" tail has moved on.