Make greenbean web server better

- Remove misguided __assert_disabled variable
- Change EPROCLIM to be EAGAIN on BSD distros
- Improve quality of greenbean with cancellations
- Fix thread race condition crash with file descriptors
This commit is contained in:
Justine Tunney 2023-09-07 03:24:46 -07:00
parent 6cff3137c5
commit 0e087143fd
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
14 changed files with 247 additions and 149 deletions

View file

@ -14,7 +14,7 @@
#define _ASSERT_H
COSMOPOLITAN_C_START_
void __assert_fail(const char *, const char *, int) relegated;
void __assert_fail(const char *, const char *, int) wontreturn relegated;
#ifdef NDEBUG
#define assert(x) ((void)0)
@ -28,7 +28,6 @@ void __assert_fail(const char *, const char *, int) relegated;
#endif
#ifdef _COSMO_SOURCE
extern bool __assert_disable;
#ifndef NDEBUG
#define unassert(x) __assert_macro(x, #x)
#define npassert(x) __assert_macro(x, #x)
@ -36,7 +35,6 @@ extern bool __assert_disable;
({ \
if (__builtin_expect(!(x), 0)) { \
__assert_fail(s, __FILE__, __LINE__); \
__builtin_trap(); \
} \
(void)0; \
})

View file

@ -164,11 +164,22 @@ static bool __sig_deliver(int sigops, int sig, int si_code, ucontext_t *ctx) {
* Returns true if signal default action is to end process.
*/
static textwindows bool __sig_is_fatal(int sig) {
if (sig == SIGCHLD || sig == SIGURG || sig == SIGWINCH) {
return false;
} else {
return true;
}
return !(sig == SIGURG || //
sig == SIGCHLD || //
sig == SIGWINCH);
}
/**
* Returns true if signal is so fatal it should dump core.
*/
static textwindows bool __sig_is_core(int sig) {
return sig == SIGSYS || //
sig == SIGBUS || //
sig == SIGSEGV || //
sig == SIGQUIT || //
sig == SIGTRAP || //
sig == SIGXCPU || //
sig == SIGXFSZ;
}
/**
@ -186,11 +197,10 @@ textwindows bool __sig_handle(int sigops, int sig, int si_code,
char *end, sigbuf[21], output[22];
signame = strsignal_r(sig, sigbuf);
STRACE("terminating due to uncaught %s", signame);
hStderr = GetStdHandle(kNtStdErrorHandle);
end = stpcpy(stpcpy(output, signame), "\n");
WriteFile(hStderr, output, end - output, 0, 0);
if (_weaken(__restore_console_win32)) {
_weaken(__restore_console_win32)();
if (__sig_is_core(sig)) {
hStderr = GetStdHandle(kNtStdErrorHandle);
end = stpcpy(stpcpy(output, signame), "\n");
WriteFile(hStderr, output, end - output, 0, 0);
}
ExitProcess(sig);
}

View file

@ -26,9 +26,7 @@
*/
void __assert_fail(const char *expr, const char *file, int line) {
char ibuf[12];
if (!__assert_disable) {
FormatInt32(ibuf, line);
tinyprint(2, file, ":", ibuf, ": assert(", expr, ") failed\n", NULL);
abort();
}
FormatInt32(ibuf, line);
tinyprint(2, "\n", file, ":", ibuf, ": assert(", expr, ") failed\n", NULL);
abort();
}

View file

@ -68,10 +68,6 @@ int raise(int sig) {
rc = sys_tkill(gettid(), sig, 0);
} else if (IsWindows() || IsMetal()) {
if (IsWindows() && sig == SIGKILL) {
// TODO(jart): Isn't this implemented by __sig_raise()?
if (_weaken(__restore_console_win32)) {
_weaken(__restore_console_win32)();
}
ExitProcess(sig);
} else {
rc = __sig_raise(sig, SI_TKILL);

View file

@ -39,10 +39,12 @@ static volatile size_t mapsize;
* @asyncsignalsafe
*/
int __ensurefds_unlocked(int fd) {
size_t n;
if (fd < g_fds.n) return fd;
g_fds.n = fd + 1;
g_fds.e = _extend(g_fds.p, g_fds.n * sizeof(*g_fds.p), g_fds.e, MAP_PRIVATE,
n = fd + 1;
g_fds.e = _extend(g_fds.p, n * sizeof(*g_fds.p), g_fds.e, MAP_PRIVATE,
kMemtrackFdsStart + kMemtrackFdsSize);
g_fds.n = n;
return fd;
}

View file

@ -1,23 +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 2022 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.
*/
/**
* Disables assert() failures at runtime.
*/
bool __assert_disable;

View file

@ -155,7 +155,6 @@ void ShowCrashReports(void) {
InstallCrashHandler(SIGILL, __got_sigill, ef); // illegal instruction
InstallCrashHandler(SIGSEGV, __got_sigsegv, ef); // bad memory access
InstallCrashHandler(SIGTRAP, __got_sigtrap, ef); // bad system call
InstallCrashHandler(SIGABRT, __got_sigabrt, ef); // abort() called
InstallCrashHandler(SIGBUS, __got_sigbus, ef); // misalign, mmap i/o failed
InstallCrashHandler(SIGURG, __got_sigurg, ef); // placeholder
GetSymbolTable();

View file

@ -690,6 +690,10 @@ errno_t clone(void *func, void *stk, size_t stksz, int flags, void *arg,
rc = ENOSYS;
}
if (SupportsBsd() && rc == EPROCLIM) {
rc = EAGAIN;
}
STRACE("clone(%t, %p, %'zu, %#x, %p, %p, %p, %p) → %s", func, stk, stksz,
flags, arg, ptid, tls, ctid, DescribeErrno(rc));

View file

@ -35,9 +35,7 @@ int ftrace_init(void);
void ftrace_hook(void);
void __morph_tls(void);
void __enable_tls(void);
void __enable_threads(void);
void *__cxa_finalize(void *);
void __restore_console_win32(void);
void __stack_chk_fail(void) wontreturn relegated;
void __stack_chk_fail_local(void) wontreturn relegated;
void _jmpstack(void *, void *, ...) wontreturn;

View file

@ -115,6 +115,7 @@ void __paginate(int, const char *);
void _weakfree(void *);
void *_mapanon(size_t) attributeallocsize((1)) mallocesque;
void *_mapshared(size_t) attributeallocsize((1)) mallocesque;
void __enable_threads(void);
void __oom_hook(size_t);
bool _isheap(void *);
/* code morphing */

View file

@ -22,11 +22,13 @@
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#include "third_party/dlmalloc/dlmalloc.h"
/**
* Releases memory of detached threads that have terminated.
*/
void pthread_decimate_np(void) {
bool empty;
struct Dll *e;
struct PosixThread *pt;
enum PosixThreadStatus status;
@ -44,5 +46,9 @@ StartOver:
goto StartOver;
}
}
empty = dll_is_empty(_pthread_list);
pthread_spin_unlock(&_pthread_lock);
if (empty) {
dlmalloc_trim(0);
}
}

View file

@ -34,6 +34,7 @@ LIBC_THREAD_A_DIRECTDEPS = \
LIBC_STR \
LIBC_SYSV \
LIBC_SYSV_CALLS \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_NSYNC \
THIRD_PARTY_NSYNC_MEM