Make locks more reliable

This change switches most of the core locks to be re-entrant, in order
to reduce the chance of deadlocking code that does, clever things with
asynchronous signal handlers. This change implements it it in pthreads
so we're one step closer to having a standardized threading primitives
This commit is contained in:
Justine Tunney 2022-06-11 01:59:26 -07:00
parent 5ea618f0af
commit c260345e06
35 changed files with 369 additions and 258 deletions

View file

@ -23,7 +23,9 @@
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/pthread.h"
#include "libc/intrin/spinlock.h"
#include "libc/limits.h"
#include "libc/macros.internal.h"
@ -74,13 +76,10 @@ struct Zipos *__zipos_get(void) {
const char *progpath;
static struct Zipos zipos;
uint8_t *map, *base, *cdir;
_Alignas(64) static int lock;
_spinlock(&lock);
if (!once) {
static pthread_mutex_t lock;
pthread_mutex_lock(&lock);
if (_cmpxchg(&once, false, true)) {
sigfillset(&neu);
if (!IsWindows()) {
sys_sigprocmask(SIG_BLOCK, &neu, &old);
}
progpath = GetProgramExecutableName();
if ((fd = open(progpath, O_RDONLY)) != -1) {
if ((size = getfiledescriptorsize(fd)) != SIZE_MAX &&
@ -104,16 +103,12 @@ struct Zipos *__zipos_get(void) {
} else {
STRACE("__zipos_get(%#s) → open failed %m", progpath);
}
if (!IsWindows()) {
sigprocmask(SIG_SETMASK, &old, 0);
}
once = true;
}
if (zipos.cdir) {
res = &zipos;
} else {
res = 0;
}
_spunlock(&lock);
pthread_mutex_unlock(&lock);
return res;
}