bofc manual pages




rb_write, rb_send - functions to put data on ring buffer  


#include <librb.h>

long rb_write(struct rb *rb, const void *buffer, size_t count);
long rb_send(struct rb *rb, const void *buffer, size_t count, unsigned long flags);  


rb_write(3) copies at most count elements from buffer to rb buffer.

Note 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 from buffer. Functions can and will try to commit as many bytes as possible in single burst, so it is better to call these functions once with big count number instead of calling it in a loop with count == 1.

Altough count is of size_t type, functions will not write 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 rb works in single-threaded mode. In this mode all calls on rb object are non blocking. This means if count elements you want to write is higher than there is space left inside buffer, function will copy only as much elements as there is space for inside rb and will immediately return. If rb_write(3) is called when buffer is full, 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 by default. That means, if you want to copy to rb more elements then there is space left, calling thread will be put to sleep - and thus will use no CPU - until someone else calls rb_read(3) to read data from buffer and makes some space.

When multiple threads access single rb object, in blocking way, it is guaranteed that each thread will write continous data. For example: consider 3 network server sockets, that receive static frames, each containing 1024 bytes of data. Now there is 1 thread for each network socket that reads from socket and puts data into rb object - in parallel of course. In such case rb guarantees that all data put this way into rb will be continous and no frame corruption will occur. But don't try this operation with MSG_DONTWAIT flag, as this may lead to situation when 1st thread will put into rb half of frame, then second thread will put its half frame, and then again first thread will put second half of its frame - now frames are corrupted and not really usable.

rb_send(3) work the same way as rb_write(3) but also accepts following flags:

Only works in multi threaded environment, on single threaded mode this is default. When passed and rb buffer contains less free elements than passed in count, function will copy all elements from buffer into rb and will return immediately. Not recommended when multiple concurent threads calls rb_write(3) with this flag - may lead to interlaced reads.


On successfull write, function will return number of elements it stored in rb. Returned value can be less than count if rb doesn't contain enough free space 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 place in rb to write data from buffer immediately
rb_stop(3) was called, and operation was cancelled, because rb object is abou 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_read(3), rb_recv(3), rb_posix_read(3), rb_posix_recv(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)