Updated: 2021/Apr/14


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

NAME
     RUN_ONCE, INIT_ONCE, FINI_ONCE - run a function exactly once

SYNOPSIS
     #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));

DESCRIPTION
     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.

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

EXAMPLES
     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.
              */
     }

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

NetBSD 9.99                     March 19, 2019                     NetBSD 9.99