| RUN_ONCE(9) | Kernel Developer's Manual | RUN_ONCE(9) | 
RUN_ONCE, INIT_ONCE,
  FINI_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));
RUN_ONCE() provides a functionality similar to
  pthread_once(3). It
  ensures that, for a given control,
  init_func() 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.
RUN_ONCE() can sleep if it's called
    concurrently.
INIT_ONCE() is used in pair with
    FINI_ONCE(). 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.
RUN_ONCE() returns what
  init_func() returned. Otherwise, it returns 0.
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.
	 */
}
| March 19, 2019 | NetBSD 9.4 |