Clean up some of the threading code

This commit is contained in:
Justine Tunney 2022-09-08 11:54:56 -07:00
parent 0547eabcd6
commit 9f963dc597
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
62 changed files with 175 additions and 582 deletions

View file

@ -1,62 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/cmpxchg.h"
#include "libc/macros.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/errfuns.h"
static struct AtFork {
volatile size_t i;
struct AtForkCallback {
void (*fn)(void *);
void *arg;
} p[ATEXIT_MAX];
} g_atfork;
/**
* Registers function to be called by fork() in child.
*
* @return 0 on success, or -1 w/ errno
* @note vfork() won't invoke callbacks
* @asyncsignalsafe
*/
int atfork(void *fn, void *arg) {
size_t i;
for (;;) {
i = g_atfork.i;
if (i == ARRAYLEN(g_atfork.p)) return enomem();
if (_cmpxchg(&g_atfork.i, i, i + 1)) {
g_atfork.p[i] = (struct AtForkCallback){.fn = fn, .arg = arg};
return 0;
}
}
}
/**
* Triggers callbacks registered by atfork().
*
* @note only fork() should call this
* @asyncsignalsafe
*/
void __onfork(void) {
size_t i;
for (i = 0; i < g_atfork.i; ++i) {
g_atfork.p[i].fn(g_atfork.p[i].arg);
}
}

View file

@ -1,6 +1,7 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STATE_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STATE_INTERNAL_H_
#include "libc/intrin/nopl.h"
#include "libc/intrin/pthread.h"
#include "libc/nexgen32e/threaded.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -9,6 +10,7 @@ hidden extern int __vforked;
hidden extern bool __time_critical;
hidden extern unsigned __sighandrvas[NSIG];
hidden extern unsigned __sighandflags[NSIG];
hidden extern pthread_mutex_t __fds_lock_obj;
hidden extern const struct NtSecurityAttributes kNtIsInheritable;
void __fds_lock(void);

View file

@ -19,7 +19,7 @@
#include "libc/calls/calls.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/errno.h"
#include "libc/intrin/once.h"
#include "libc/intrin/pthread.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/enum/symboliclink.h"
@ -35,17 +35,20 @@
__msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW;
static bool AllowedToCreateSymlinks(void) {
static _Bool g_winlink_allowed;
static pthread_once_t g_winlink_once;
static textwindows void InitializeWinlink(void) {
int64_t tok;
struct NtLuid id;
struct NtTokenPrivileges tp;
if (!OpenProcessToken(GetCurrentProcess(), kNtTokenAllAccess, &tok)) return 0;
if (!LookupPrivilegeValue(0, u"SeCreateSymbolicLinkPrivilege", &id)) return 0;
if (!OpenProcessToken(GetCurrentProcess(), kNtTokenAllAccess, &tok)) return;
if (!LookupPrivilegeValue(0, u"SeCreateSymbolicLinkPrivilege", &id)) return;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = id;
tp.Privileges[0].Attributes = kNtSePrivilegeEnabled;
if (!AdjustTokenPrivileges(tok, 0, &tp, sizeof(tp), 0, 0)) return 0;
return GetLastError() != kNtErrorNotAllAssigned;
if (!AdjustTokenPrivileges(tok, 0, &tp, sizeof(tp), 0, 0)) return;
g_winlink_allowed = GetLastError() != kNtErrorNotAllAssigned;
}
textwindows int sys_symlinkat_nt(const char *target, int newdirfd,
@ -79,7 +82,8 @@ textwindows int sys_symlinkat_nt(const char *target, int newdirfd,
// windows only lets administrators do this
// even then we're required to ask for permission
if (!_once(AllowedToCreateSymlinks())) {
pthread_once(&g_winlink_once, InitializeWinlink);
if (!g_winlink_allowed) {
return eperm();
}