bofc manual pages




rb_read, rb_recv - functions to retrieve data from ring buffer  


#include <librb.h>

long rb_read(struct rb *rb, void *buffer, size_t count);
long rb_recv(struct rb *rb, void *buffer, size_t count, unsigned long flags);



rb_read(3) copies at most count elements from ring buffer rb to memory pointed by buffer

Note that by elements we don't mean bytes. For example if object_size is 4 bytes, and count is 3, this will copy 4 * 3 = 12 bytes into buffer. Functions can and will try to commit as many bytes as possible in a single burst, so it is better to call these function once with big count number than call it in a loop with count == 1.

Altough count is of size_t type, functions will not read more than LONG_MAX elements. If count is bigger than LONG_MAX it will be set to LONG_MAX internaly anyway. Also make sure that formula count * rb->object_size does not exceed size_t type or you will overflow internal integer and that will result in Undefined Behaviour.

By default buffer works in single-threaded mode. In this mode all calls on rb object are non blocking. This means if count elements you want to read is higher than there is inside buffer, function will copy only as much elements as there are inside rb and will return. If rb_read(3) is called when buffer is empty, EAGAIN error will be returned.

If library has been built with pthread support, and rb was created with O_MULTITHREAD flag, all functions will be blocking calls. That means if you want to copy more elements then there is inside rb object, calling thread will be put to sleep - and thus will use no CPU - until someone else calls rb_write(3) to write data to buffer and total count elements have been copied into buffer.

When multiple threads access single rb object in blocking mode, it is guaranteed that each thread will write from rb to buffer continous data. Consider rb object with 10 message in the rb each containing 20 bytes frame. Now 4 threads simultaneously calls rb_read(3) to read data from rb to buffer. In such scenario rb guarantees all frames will be read from rb in order without interlace even when rb is currently empty and waits for rb_write(3) to feed it some data.

rb_recv(3) work the same as rb_read(3) but it also accepts flags. Possible flags are:

Only works in multi threaded environment, on single threaded mode this is default. When passed and rb buffer contains less elements than passed in count, function will copy all bytes from rb into buffer and will return immediately. This means, function will never block, no matter what. Not recommended when multiple threads calls rb_read(3) with this flag - may lead to interlaced reads
Reads from rb into buffer as normal, but doesn't remove data from rb, so consecutive calls to this function will return same data (provided that nobody called rb_recv(3) without this flag). When this is called in threaded environment enabled, functions will act as if MSG_DONTWAIT flag was also passed. It is guaranteed that calling function with this flag, will not alter internal state of rb object.


On successfull read, function will return number of elements it read and stored in buffer. Returned value can be less than count if rb doesn't contain enough data and function operates in non blocking mode. On errors function returns -1, in such case, rb buffer is left intact.  


Any of the passed pointers is NULL.
This error will be set, when rb is operating in non blocking mode, and there is no data to be read from rb immediately.
rb_stop(3) was called, and operation was cancelled, because rb object is about to be destroyed. You should not access rb object after you receive this error. Otherwise you will probably get deadlock or application will crash. Returned only if threads are enabled.


rb_overview(7), rb_new(3), rb_init(3), rb_destroy(3), rb_cleanup(3), rb_discard(3), rb_stop(3), rb_stop_signal(3), rb_write(3), rb_send(3), rb_posix_write(3), rb_posix_send(3), rb_clear(3), rb_count(3), rb_space(3), rb_header_size(3), rb_array_size(3), rb_version(3)


23 October 2018 (v1.1.0)