mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-01 00:38:31 +00:00
Make forking off threads reliable on Windows
This change makes posix_spawn_test no longer flaky on Windows, by (1) fixing a race condition in wait(), and (2) removing a misguided vfork implementation which was letting Windows bypass pthread_atfork().
This commit is contained in:
parent
2ebc5781a1
commit
58352df0a4
30 changed files with 230 additions and 187 deletions
|
@ -67,7 +67,7 @@ textwindows int sys_accept_nt(struct Fd *fd, struct sockaddr_storage *addr,
|
|||
if (!AcceptEx(fd->handle, handle, &buffer, 0, sizeof(buffer.local),
|
||||
sizeof(buffer.remote), &bytes_received, &overlapped)) {
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
if (__wsablock(fd, &overlapped, &completion_flags, true,
|
||||
if (__wsablock(fd, &overlapped, &completion_flags, kSigOpRestartable,
|
||||
sockfd->rcvtimeo) == -1) {
|
||||
WSACloseEvent(overlapped.hEvent);
|
||||
__sys_closesocket_nt(handle);
|
||||
|
|
|
@ -47,7 +47,8 @@ textwindows ssize_t sys_recv_nt(struct Fd *fd, const struct iovec *iov,
|
|||
} else {
|
||||
errno = err;
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
rc = __wsablock(fd, &overlapped, &flags, true, sockfd->rcvtimeo);
|
||||
rc = __wsablock(fd, &overlapped, &flags, kSigOpRestartable,
|
||||
sockfd->rcvtimeo);
|
||||
}
|
||||
unassert(WSACloseEvent(overlapped.hEvent));
|
||||
return rc;
|
||||
|
|
|
@ -46,7 +46,8 @@ textwindows ssize_t sys_recvfrom_nt(struct Fd *fd, const struct iovec *iov,
|
|||
} else {
|
||||
errno = err;
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
rc = __wsablock(fd, &overlapped, &flags, true, sockfd->rcvtimeo);
|
||||
rc = __wsablock(fd, &overlapped, &flags, kSigOpRestartable,
|
||||
sockfd->rcvtimeo);
|
||||
}
|
||||
WSACloseEvent(overlapped.hEvent);
|
||||
return rc;
|
||||
|
|
|
@ -41,7 +41,8 @@ textwindows ssize_t sys_send_nt(int fd, const struct iovec *iov, size_t iovlen,
|
|||
}
|
||||
} else {
|
||||
sockfd = (struct SockFd *)g_fds.p[fd].extra;
|
||||
rc = __wsablock(g_fds.p + fd, &overlapped, &flags, true, sockfd->sndtimeo);
|
||||
rc = __wsablock(g_fds.p + fd, &overlapped, &flags, kSigOpRestartable,
|
||||
sockfd->sndtimeo);
|
||||
}
|
||||
WSACloseEvent(overlapped.hEvent);
|
||||
return rc;
|
||||
|
|
|
@ -57,7 +57,7 @@ static textwindows int SendfileBlock(int64_t handle,
|
|||
NTTRACE("WSAWaitForMultipleEvents failed %lm");
|
||||
return __winsockerr();
|
||||
} else if (i == kNtWaitTimeout || i == kNtWaitIoCompletion) {
|
||||
if (_check_interrupts(true, g_fds.p)) return -1;
|
||||
if (_check_interrupts(kSigOpRestartable, g_fds.p)) return -1;
|
||||
#if _NTTRACE
|
||||
POLLTRACE("WSAWaitForMultipleEvents...");
|
||||
#endif
|
||||
|
|
|
@ -42,7 +42,8 @@ textwindows ssize_t sys_sendto_nt(int fd, const struct iovec *iov,
|
|||
}
|
||||
} else {
|
||||
sockfd = (struct SockFd *)g_fds.p[fd].extra;
|
||||
rc = __wsablock(g_fds.p + fd, &overlapped, &flags, true, sockfd->sndtimeo);
|
||||
rc = __wsablock(g_fds.p + fd, &overlapped, &flags, kSigOpRestartable,
|
||||
sockfd->sndtimeo);
|
||||
}
|
||||
WSACloseEvent(overlapped.hEvent);
|
||||
return rc;
|
||||
|
|
|
@ -20,7 +20,7 @@ int sys_shutdown_nt(struct Fd *, int);
|
|||
ssize_t sys_recv_nt(struct Fd *, const struct iovec *, size_t, uint32_t);
|
||||
ssize_t sys_recvfrom_nt(struct Fd *, const struct iovec *, size_t, uint32_t,
|
||||
void *, uint32_t *);
|
||||
int __wsablock(struct Fd *, struct NtOverlapped *, uint32_t *, bool, uint32_t);
|
||||
int __wsablock(struct Fd *, struct NtOverlapped *, uint32_t *, int, uint32_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -37,8 +37,7 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int __wsablock(struct Fd *fd, struct NtOverlapped *overlapped,
|
||||
uint32_t *flags, bool restartable,
|
||||
uint32_t timeout) {
|
||||
uint32_t *flags, int sigops, uint32_t timeout) {
|
||||
int e, rc;
|
||||
uint32_t i, got;
|
||||
if (WSAGetLastError() != kNtErrorIoPending) {
|
||||
|
@ -51,7 +50,7 @@ textwindows int __wsablock(struct Fd *fd, struct NtOverlapped *overlapped,
|
|||
WSAGetLastError() == kNtErrorNotFound);
|
||||
errno = e;
|
||||
} else {
|
||||
if (_check_interrupts(restartable, g_fds.p)) {
|
||||
if (_check_interrupts(sigops, g_fds.p)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +61,7 @@ textwindows int __wsablock(struct Fd *fd, struct NtOverlapped *overlapped,
|
|||
NTTRACE("WSAWaitForMultipleEvents failed %lm");
|
||||
return __winsockerr();
|
||||
} else if (i == kNtWaitTimeout || i == kNtWaitIoCompletion) {
|
||||
if (_check_interrupts(restartable, g_fds.p)) {
|
||||
if (_check_interrupts(sigops, g_fds.p)) {
|
||||
return -1;
|
||||
}
|
||||
if (timeout) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue