From 58ad6127dadf5d2a45be99d5f434a49eb66b1279 Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 3 Apr 2022 16:52:50 +0000 Subject: [PATCH] Initialize the mutex before making us of it from many threads. Prevents a race in which one thread is currently initializing the mutex which is not an atomic operation whereas another thread tries to use it too early. With and ok schwarze@ --- regress/lib/libc/locale/uselocale/uselocale.c | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/regress/lib/libc/locale/uselocale/uselocale.c b/regress/lib/libc/locale/uselocale/uselocale.c index 445bb64876a..f07a16ad651 100644 --- a/regress/lib/libc/locale/uselocale/uselocale.c +++ b/regress/lib/libc/locale/uselocale/uselocale.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uselocale.c,v 1.5 2017/08/16 13:52:50 schwarze Exp $ */ +/* $OpenBSD: uselocale.c,v 1.6 2022/04/03 16:52:50 anton Exp $ */ /* * Copyright (c) 2017 Ingo Schwarze * @@ -170,6 +170,10 @@ _test_MB_CUR_MAX(int line, int ee, size_t ar) #define TEST_R(Fn, ...) _test_##Fn(__LINE__, 0, __VA_ARGS__) #define TEST_ER(Fn, ...) _test_##Fn(__LINE__, __VA_ARGS__) +static pthread_mutex_t mtx; +static pthread_mutexattr_t mtxattr; +static pthread_cond_t cond; + /* * SWITCH_SIGNAL wakes the other thread. * SWITCH_WAIT goes to sleep. @@ -179,40 +183,21 @@ _test_MB_CUR_MAX(int line, int ee, size_t ar) static void switch_thread(int step, int flags) { - static pthread_mutexattr_t ma; - static struct timespec t; - static pthread_cond_t *c; - static pthread_mutex_t *m; - int irc; - - if (m == NULL) { - if ((m = malloc(sizeof(*m))) == NULL) - err(1, NULL); - if ((irc = pthread_mutexattr_init(&ma)) != 0) - errc(1, irc, "pthread_mutexattr_init"); - if ((irc = pthread_mutexattr_settype(&ma, - PTHREAD_MUTEX_STRICT_NP)) != 0) - errc(1, irc, "pthread_mutexattr_settype"); - if ((irc = pthread_mutex_init(m, &ma)) != 0) - errc(1, irc, "pthread_mutex_init"); - } - if (c == NULL) { - if ((c = malloc(sizeof(*c))) == NULL) - err(1, NULL); - if ((irc = pthread_cond_init(c, NULL)) != 0) - errc(1, irc, "pthread_cond_init"); - } + struct timespec t; + int irc; + if (flags & SWITCH_SIGNAL) { - if ((irc = pthread_cond_signal(c)) != 0) + if ((irc = pthread_cond_signal(&cond)) != 0) errc(1, irc, "pthread_cond_signal(%d)", step); } if (flags & SWITCH_WAIT) { - if ((irc = pthread_mutex_trylock(m)) != 0) + if ((irc = pthread_mutex_trylock(&mtx)) != 0) errc(1, irc, "pthread_mutex_trylock(%d)", step); t.tv_sec = time(NULL) + 2; - if ((irc = pthread_cond_timedwait(c, m, &t)) != 0) + t.tv_nsec = 0; + if ((irc = pthread_cond_timedwait(&cond, &mtx, &t)) != 0) errc(1, irc, "pthread_cond_timedwait(%d)", step); - if ((irc = pthread_mutex_unlock(m)) != 0) + if ((irc = pthread_mutex_unlock(&mtx)) != 0) errc(1, irc, "pthread_mutex_unlock(%d)", step); } } @@ -442,6 +427,16 @@ main(void) unsetenv("LC_MESSAGES"); unsetenv("LANG"); + if ((irc = pthread_mutexattr_init(&mtxattr)) != 0) + errc(1, irc, "pthread_mutexattr_init"); + if ((irc = pthread_mutexattr_settype(&mtxattr, + PTHREAD_MUTEX_STRICT_NP)) != 0) + errc(1, irc, "pthread_mutexattr_settype"); + if ((irc = pthread_mutex_init(&mtx, &mtxattr)) != 0) + errc(1, irc, "pthread_mutex_init"); + if ((irc = pthread_cond_init(&cond, NULL)) != 0) + errc(1, irc, "pthread_cond_init"); + /* First let the child do some tests. */ if ((irc = pthread_create(&child_thread, NULL, child_func, NULL)) != 0) errc(1, irc, "pthread_create"); -- 2.20.1