-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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@
- Loading branch information
anton
committed
Apr 3, 2022
1 parent
9ce2f3a
commit 1e373d2
Showing
1 changed file
with
23 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <[email protected]> | ||
* | ||
|
@@ -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"); | ||
|