man.bsd.lv manual page server

Manual Page Search Parameters

RUN_ONCE(9) Kernel Developer's Manual RUN_ONCE(9)

RUN_ONCE, INIT_ONCE, FINI_ONCErun a function exactly once

#include <sys/once.h>

ONCE_DECL(control);

int
RUN_ONCE(once_t *control, int (*init_func)(void));

int
INIT_ONCE(once_t *control, int (*init_func)(void));

void
FINI_ONCE(once_t *control, void (*fini_func)(void));

() provides a functionality similar to pthread_once(3). It ensures that, for a given control, () is executed (successfully) exactly once. It is considered as a successful execution if and only if init_func() returned 0. As long as there was no successful execution, RUN_ONCE() will try again each time it is called.

() can sleep if it's called concurrently.

() is used in pair with (). INIT_ONCE() will only be run once similar to RUN_ONCE(). FINI_ONCE() will only be run at last time if it is called as many times as calling INIT_ONCE(). When FINI_ONCE() is executed, the next call to INIT_ONCE() will be executed again. That is, INIT_ONCE() and FINI_ONCE() can be nested.

On failure, RUN_ONCE() returns what init_func() returned. Otherwise, it returns 0.

The following example shows how RUN_ONCE() is used. Regardless of how many times some_func() is executed, init_func() will be executed exactly once.

static int
init_func(void)
{

	/*
	 * do some initialization.
	 */

	return 0; /* success */
}

int
some_func(void)
{
	static ONCE_DECL(control);

	RUN_ONCE(&control, init_func);

	/*
	 * we are sure that init_func has already been completed here.
	 */
}

pthread_once(3), condvar(9), intro(9)

March 19, 2019 NetBSD-9.2