Skip to content

Development (re usage)

Sebastian Reimers edited this page Aug 9, 2023 · 12 revisions

Development

Include headers

Preferred order:

  1. System/Third party headers
  2. libre headers
  3. Local/Custom headers

Example

#include <string.h>
#include <re.h>
#include "custom.h"

Within libre itself use the specific headers like re_types.h etc.

Conflicting macro definitions

You can #undef conflicting definitions before libre header include:

#include <sys/queue.h>
#undef LIST_INIT
#undef LIST_FOREACH
#include <re.h>

Multithreading

Async Workers

Usage:

re_thread_async(blocking_work, callback, data);

Example:

#include <re.h>

enum { JOBS = 100 };

static int cnt = 0;


static int work(void *arg)
{
	(void)arg;
	
	sys_msleep(10);
	
	return 0;
}


static void callback(int err, void *arg)
{
	(void)arg;
	(void)err;

	if (++cnt >= JOBS)
		re_cancel();
}


int main(void)
{
	libre_init();
	re_thread_async_init(16);

	for (int i = 0; i < JOBS; i++) {
		re_thread_async(work, callback, NULL);
	}

	re_main(NULL);

	re_thread_async_close();
	libre_close();
}

Multiple worker eventloops

By default re_main() is single threaded. You can register multiple worker threads with re_thread_init() like so:

static int thread_handler(void *arg)
{
  re_thread_init();
  /* register network/tmr callbacks */      
  err = re_main(NULL); /* Start new worker eventloop */
  re_thread_close();
}

...
thr_t tid;
thrd_create(&tid, thread_handler, NULL);
...

Keep in mind the new worker eventloop only handles file descriptors which are registered by the same thread (fd_listen). You can use fd_close and fd_listen to detach/attach file descriptors from another thread (e.g. main thread). For example udp has already some nice helpers for this "udp_thread_attach/udp_thread_detach".

See retest remain.c for a complete example.

Thread-safety for non-re threads

If you need to call functions from another thread you can use re_thread_leave and re_thread_enter. This works only for the first re main thread and not for other re worker threads. For details see: https://github.com/baresip/baresip/wiki/Using-baresip-as-a-library#examples-using-re-lock

Assert (re_assert helper) handling

cmake -B build -DCMAKE_BUILD_TYPE=Debug

int err;
re_assert(err = myfunc()); /* myfunc() is executed and assert() calls abort() if expr is false */
re_assert_se(err = myfunc()); /* myfunc() is executed and assert() calls abort() if expr is false  */

cmake -B build -DCMAKE_BUILD_TYPE=Release

int err;
re_assert(err = myfunc()); /* myfunc() and assert() are not executed in release builds */
re_assert_se(err = myfunc()); /* myfunc() is executed in release build (keeps side effect) but assert() is not called */