bofc manual pages
int rb_stop(struct rb *rb);
int rb_stop_signal(struct rb *rb, int signum);
int rb_destroy(struct rb *rb);
int rb_cleanup(struct rb *rb);
Feature Test Macro:
- ENABLE_THREADS && ENABLE_POSIX_CALLS
Function rb_stop(3) spawns thread (and then exits) that forces any locked thread to exit from rb_read(3) or rb_send(3). Also after this function is called, any call to rb_read(3) or rb_send(3) will result in error.
When ENABLE_THREADS and ENABLE_POSIX_CALLS are enabled and rb object was created with O_MULTITHREAD, rb_write(3) and rb_read(3) may be blocked in select() function and the only way for thread to leave blocked syscall is to send a signal. rb_stop(3) will send signum signal to all threads blocked in syscalls to release them so caller can join them in main thread. By default SIGUSR1 is sent. If you use this signal in your application, you can overwrite signal rb_stop(3) will send with rb_stop_signal(3) function.
Function rb_destroy(3) simply frees all resources allocated by rb_new(3). If rb_stop(3) was called before, function will stop spawned thread. After calling this, rb that was freed, cannot be used anymore without calling rb_new(3) first. Passing same rb object twice, will result in segmentation fault.
Due to nature of pthread, you must be sure that no threads are calling any functions from librb before calling rb_destroy(3) or rb_cleanup(3). Failing to do so, will lead to deadlocks or crashes sooner or later.
If you cannot stop threads by yourself before calling rb_destroy(3), you can use rb_stop(3) function, to force all threads to exit, then join them, and after that destroy rb object. Look at below example.
void *consumer(void *arg)
struct rb *rb = arg;
int v, e;
if (rb_read(rb, &v, 1) != 0)
if (errno == ECANCELED)
/* function was forced to exit, we should stop thread
* or at least make sure we don't access rb_* functions
/* more code */
/* some code */
for (int i = 0; i != 10; ++i)
pthread_create(&consumers[i], NULL, consumer, rb);
/* wait for some event */
/* force all consumer threads to exit even if they are locked
* in some conditional variables
for (i = 0; i != 10; ++i)
/* make sure all consumer threads stopped, and none will access
* any rb_* functions
- Passed rb is invalid (null).
- Invalid signum passed in rb_stop_signal(3) function. Invalid as in signal does not exist on the system or SIGKILL or SIGSTOP was passed which cannot be caught. In that case signal is not changed.
- Function not implemented (feature macro not set)
rb_overview(7), rb_new(3), rb_init(3), rb_read(3), rb_discard(3), rb_recv(3), rb_write(3), rb_send(3), rb_posix_read(3), rb_posix_recv(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)