mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-05 09:20:29 +00:00
Fix fork locking on win32
- __enable_threads / set __threaded in __proc_setup as threads are required for win32 subprocess management - move mmi/fds locking out of pthread_atfork.c into fork.c so it's done anytime __threaded is set instead of being dependent of pthreads - explicitly yoink _pthread_onfork_prepare, _pthread_onfork_parent, and _pthread_onfork_child in pthread_create.c so they are linked in in-case they are separated from _pthread_atfork Big Thanks to @dfyz for help with locating the issue, testing, and devising a fix!
This commit is contained in:
parent
6e6fc38935
commit
2721ad46ea
4 changed files with 26 additions and 9 deletions
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
|
@ -34,12 +35,29 @@
|
|||
#include "libc/nt/thread.h"
|
||||
#include "libc/proc/proc.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
static void _onfork_prepare(void) {
|
||||
if (_weaken(_pthread_onfork_prepare)) {
|
||||
_weaken(_pthread_onfork_prepare)();
|
||||
}
|
||||
__fds_lock();
|
||||
__mmi_lock();
|
||||
}
|
||||
|
||||
static void _onfork_parent(void) {
|
||||
__mmi_unlock();
|
||||
__fds_unlock();
|
||||
if (_weaken(_pthread_onfork_parent)) {
|
||||
_weaken(_pthread_onfork_parent)();
|
||||
}
|
||||
}
|
||||
|
||||
int _fork(uint32_t dwCreationFlags) {
|
||||
struct Dll *e;
|
||||
int ax, dx, tid, parent;
|
||||
|
@ -47,8 +65,8 @@ int _fork(uint32_t dwCreationFlags) {
|
|||
BLOCK_SIGNALS;
|
||||
if (IsWindows())
|
||||
__proc_lock();
|
||||
if (__threaded && _weaken(_pthread_onfork_prepare)) {
|
||||
_weaken(_pthread_onfork_prepare)();
|
||||
if (__threaded) {
|
||||
_onfork_prepare();
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
ax = sys_fork();
|
||||
|
@ -105,8 +123,8 @@ int _fork(uint32_t dwCreationFlags) {
|
|||
STRACE("fork() → 0 (child of %d)", parent);
|
||||
} else {
|
||||
// this is the parent process
|
||||
if (__threaded && _weaken(_pthread_onfork_parent)) {
|
||||
_weaken(_pthread_onfork_parent)();
|
||||
if (__threaded) {
|
||||
_onfork_parent();
|
||||
}
|
||||
if (IsWindows())
|
||||
__proc_unlock();
|
||||
|
|
|
@ -233,6 +233,7 @@ static textwindows dontinstrument uint32_t __proc_worker(void *arg) {
|
|||
* Lazy initializes process tracker data structures and worker.
|
||||
*/
|
||||
static textwindows void __proc_setup(void) {
|
||||
__enable_threads();
|
||||
__proc.onbirth = CreateEvent(0, 0, 0, 0); // auto reset
|
||||
__proc.haszombies = CreateEvent(0, 1, 0, 0); // manual reset
|
||||
__proc.thread = CreateThread(0, 65536, __proc_worker, 0,
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/proc/proc.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
|
@ -66,13 +65,9 @@ static void _pthread_onfork(int i) {
|
|||
void _pthread_onfork_prepare(void) {
|
||||
_pthread_onfork(0);
|
||||
_pthread_lock();
|
||||
__fds_lock();
|
||||
__mmi_lock();
|
||||
}
|
||||
|
||||
void _pthread_onfork_parent(void) {
|
||||
__mmi_unlock();
|
||||
__fds_unlock();
|
||||
_pthread_unlock();
|
||||
_pthread_onfork(1);
|
||||
}
|
||||
|
|
|
@ -60,6 +60,9 @@ __static_yoink("nsync_mu_trylock");
|
|||
__static_yoink("nsync_mu_rlock");
|
||||
__static_yoink("nsync_mu_runlock");
|
||||
__static_yoink("_pthread_atfork");
|
||||
__static_yoink("_pthread_onfork_prepare");
|
||||
__static_yoink("_pthread_onfork_parent");
|
||||
__static_yoink("_pthread_onfork_child");
|
||||
|
||||
#define MAP_ANON_OPENBSD 0x1000
|
||||
#define MAP_STACK_OPENBSD 0x4000
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue