> I can confirm that your patch fixes the issue here. Great. Thanks.
Testing showed a regression: glthread_once is no longer working on FreeBSD 11, because in this code # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ (pthread_in_use () \ ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) pthread_in_use () now evaluates to 1, and pthread_once from libc returns ENOSYS. Thus glthread_once returns ENOSYS, and gl_once calls abort(). This patch fixes it. 2020-01-20 Bruno Haible <br...@clisp.org> lock: Fix test-once1 failure on FreeBSD 11 (regression from 2020-01-19). * lib/glthread/lock.c (glthread_once_multithreaded): New function. * lib/glthread/lock.h (glthread_once_multithreaded): New declaration. (glthread_once): Use it. diff --git a/lib/glthread/lock.c b/lib/glthread/lock.c index 6336591..1f6f713 100644 --- a/lib/glthread/lock.c +++ b/lib/glthread/lock.c @@ -718,6 +718,26 @@ glthread_once_singlethreaded (pthread_once_t *once_control) return 0; } +# if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) + +int +glthread_once_multithreaded (pthread_once_t *once_control, + void (*init_function) (void)) +{ + int err = pthread_once (once_control, init_function); + if (err == ENOSYS) + { + /* This happens on FreeBSD 11: The pthread_once function in libc returns + ENOSYS. */ + if (glthread_once_singlethreaded (once_control)) + init_function (); + return 0; + } + return err; +} + +# endif + #endif /* ========================================================================= */ diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h index 9c70f4e..1de86fe 100644 --- a/lib/glthread/lock.h +++ b/lib/glthread/lock.h @@ -505,10 +505,19 @@ extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *l typedef pthread_once_t gl_once_t; # define gl_once_define(STORAGECLASS, NAME) \ STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; -# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ - (pthread_in_use () \ - ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ - : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) +# if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ + (pthread_in_use () \ + ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ + : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) +# else +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ + (pthread_in_use () \ + ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ + : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) +extern int glthread_once_multithreaded (pthread_once_t *once_control, + void (*init_function) (void)); +# endif extern int glthread_once_singlethreaded (pthread_once_t *once_control); # ifdef __cplusplus