diff --git a/libc/calls/internal.h b/libc/calls/internal.h index eb85e9d6e..a05c67988 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -306,6 +306,8 @@ int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden; │ cosmopolitan § syscalls » windows nt » support ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ +bool _check_sigchld(void) hidden; +int __sample_pids(int[hasatleast 64], int64_t[hasatleast 64]) hidden; bool isdirectory_nt(const char *) hidden; bool isregularfile_nt(const char *) hidden; bool issymlink_nt(const char *) hidden; diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index 374f273de..f0bd2629b 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" +#include "libc/bits/bits.h" #include "libc/bits/weaken.h" #include "libc/calls/internal.h" #include "libc/calls/struct/iovec.h" @@ -46,7 +47,11 @@ textwindows ssize_t sys_read_nt(struct Fd *fd, const struct iovec *iov, ssize_t rc; uint32_t size; size_t i, total; - if (weaken(_check_sigwinch) && weaken(_check_sigwinch)(fd)) return eintr(); + if (cmpxchg(&__interrupted, true, false) || + (weaken(_check_sigchld) && weaken(_check_sigchld)()) || + (weaken(_check_sigwinch) && weaken(_check_sigwinch)(fd))) { + return eintr(); + } while (iovlen && !iov[0].iov_len) iov++, iovlen--; if (iovlen) { for (total = i = 0; i < iovlen; ++i) { diff --git a/libc/calls/samplepids.c b/libc/calls/samplepids.c new file mode 100644 index 000000000..d8603752b --- /dev/null +++ b/libc/calls/samplepids.c @@ -0,0 +1,46 @@ +/*-*- 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. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/rand/lcg.internal.h" + +/** + * Returns handles of windows pids being tracked. + * + * We return 64 at most because Windows can't await on a larger number + * of things at the same time. If we have a lot of subprocesses, then we + * choose a subgroup to monitor at random. + * + * @return number of items returned in pids and handles + */ +int __sample_pids(int pids[hasatleast 64], int64_t handles[hasatleast 64]) { + static uint64_t rando = 1; + uint32_t i, j, base, count; + base = KnuthLinearCongruentialGenerator(&rando); + for (count = i = 0; i < g_fds.n; ++i) { + j = (base + i) % g_fds.n; + if (g_fds.p[j].kind == kFdProcess) { + pids[count] = j; + handles[count] = g_fds.p[j].handle; + if (++count == 64) { + break; + } + } + } + return count; +} diff --git a/libc/calls/sigchld-nt.c b/libc/calls/sigchld-nt.c new file mode 100644 index 000000000..d06a23eff --- /dev/null +++ b/libc/calls/sigchld-nt.c @@ -0,0 +1,55 @@ +/*-*- 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. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/calls/typedef/sigaction_f.h" +#include "libc/nt/enum/status.h" +#include "libc/nt/enum/wait.h" +#include "libc/nt/runtime.h" +#include "libc/nt/synchronization.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" + +/** + * Checks to see if SIGCHLD should be raised on Windows. + * @return true if a signal was raised + */ +bool _check_sigchld(void) { + siginfo_t si; + int pids[64]; + uint32_t i, n; + int64_t handles[64]; + if (__sighandrvas[SIGCHLD] < kSigactionMinRva) return false; + if (!(n = __sample_pids(pids, handles))) return false; + i = WaitForMultipleObjects(n, handles, false, 0); + if (i == kNtWaitTimeout) return false; + if (i == kNtWaitFailed) { + STRACE("%s failed %u", "WaitForMultipleObjects", GetLastError()); + return false; + } + STRACE("SIGCHLD fd=%d handle=%ld", pids[i], handles[i]); + bzero(&si, sizeof(si)); + si.si_signo = SIGCHLD; + si.si_code = CLD_EXITED; + si.si_pid = pids[i]; + ((sigaction_f)(_base + __sighandrvas[SIGCHLD]))(SIGCHLD, &si, 0); + return true; +} diff --git a/libc/calls/sigwinch-nt.c b/libc/calls/sigwinch-nt.c index b62ac6ef0..6c01ed637 100644 --- a/libc/calls/sigwinch-nt.c +++ b/libc/calls/sigwinch-nt.c @@ -23,6 +23,7 @@ #include "libc/errno.h" #include "libc/nt/struct/consolescreenbufferinfoex.h" #include "libc/str/str.h" +#include "libc/sysv/consts/sig.h" static struct winsize __ws; @@ -42,6 +43,7 @@ textwindows bool _check_sigwinch(struct Fd *fd) { ws.ws_col, ws.ws_row); if (__sighandrvas[SIGWINCH] >= kSigactionMinRva) { bzero(&si, sizeof(si)); + si.si_signo = SIGWINCH; ((sigaction_f)(_base + __sighandrvas[SIGWINCH]))(SIGWINCH, &si, 0); return true; } diff --git a/libc/calls/wait4-nt.c b/libc/calls/wait4-nt.c index 35a1b7e07..0cb2dafac 100644 --- a/libc/calls/wait4-nt.c +++ b/libc/calls/wait4-nt.c @@ -33,6 +33,7 @@ #include "libc/nt/struct/filetime.h" #include "libc/nt/struct/processmemorycounters.h" #include "libc/nt/synchronization.h" +#include "libc/rand/lcg.internal.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" @@ -45,10 +46,14 @@ textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options, int64_t handle; int64_t handles[64]; uint32_t dwExitCode; - uint32_t i, count, timeout; + uint32_t i, j, base, count, timeout; struct NtProcessMemoryCountersEx memcount; struct NtFileTime createfiletime, exitfiletime, kernelfiletime, userfiletime; - if (pid != -1) { + if (pid != -1 && pid != 0) { + if (pid < 0) { + /* XXX: this is sloppy */ + pid = -pid; + } if (!__isfdkind(pid, kFdProcess)) { /* XXX: this is sloppy (see fork-nt.c) */ if (!__isfdopen(pid) && @@ -70,16 +75,8 @@ textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options, pids[0] = pid; count = 1; } else { - for (count = 0, i = g_fds.n; i--;) { - if (g_fds.p[i].kind == kFdProcess) { - pids[count] = i; - handles[count] = g_fds.p[i].handle; - if (++count == ARRAYLEN(handles)) break; - } - } - if (!count) { - return echild(); - } + count = __sample_pids(pids, handles); + if (!count) return echild(); } for (;;) { dwExitCode = kNtStillActive; diff --git a/libc/intrin/asan.c b/libc/intrin/asan.c index 0d6157f07..e3f62b7cc 100644 --- a/libc/intrin/asan.c +++ b/libc/intrin/asan.c @@ -27,6 +27,7 @@ #include "libc/calls/struct/iovec.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/asancodes.h" #include "libc/intrin/kprintf.h" #include "libc/log/backtrace.internal.h" #include "libc/log/internal.h" @@ -1256,6 +1257,14 @@ void *__asan_get_current_fake_stack(void) { return 0; } +void __sanitizer_annotate_contiguous_container(long beg, long end, long old_mid, + long new_mid) { + // the c++ stl uses this + // TODO(jart): make me faster + __asan_unpoison(beg, new_mid - beg); + __asan_poison(new_mid, end - new_mid, kAsanHeapOverrun); +} + void __asan_install_malloc_hooks(void) { HOOK(hook_free, __asan_free); HOOK(hook_malloc, __asan_malloc); diff --git a/libc/intrin/exit.greg.c b/libc/intrin/exit.greg.c index caa199ee9..599b5ec63 100644 --- a/libc/intrin/exit.greg.c +++ b/libc/intrin/exit.greg.c @@ -17,20 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #define ShouldUseMsabiAttribute() 1 -#include "libc/calls/internal.h" #include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/nexgen32e/vendor.internal.h" -#include "libc/nt/console.h" -#include "libc/nt/process.h" #include "libc/nt/runtime.h" -#include "libc/nt/thunk/msabi.h" -#include "libc/runtime/internal.h" #include "libc/sysv/consts/nr.h" -uint32_t __winmainpid; -const char kConsoleHandles[2] = {kNtStdInputHandle, kNtStdOutputHandle}; - /** * Terminates process, ignoring destructors and atexit() handlers. * @@ -45,11 +37,6 @@ const char kConsoleHandles[2] = {kNtStdInputHandle, kNtStdOutputHandle}; privileged noinstrument noasan noubsan wontreturn void _Exit(int exitcode) { int i; STRACE("_Exit(%d)", exitcode); - if (SupportsWindows() && GetCurrentProcessId() == __winmainpid) { - for (i = 0; i < 2; ++i) { - SetConsoleMode(GetStdHandle(kConsoleHandles[i]), __ntconsolemode[i]); - } - } if ((!IsWindows() && !IsMetal()) || (IsMetal() && IsGenuineCosmo())) { asm volatile("syscall" : /* no outputs */ diff --git a/libc/intrin/quick_exit.c b/libc/intrin/quick_exit.c index 820664cc8..759d941d2 100644 --- a/libc/intrin/quick_exit.c +++ b/libc/intrin/quick_exit.c @@ -20,11 +20,15 @@ #include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/nt/console.h" +#include "libc/nt/process.h" #include "libc/nt/runtime.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" +uint32_t __winmainpid; +const char kConsoleHandles[2] = {kNtStdInputHandle, kNtStdOutputHandle}; + /** * Exits process faster. * @@ -35,6 +39,11 @@ wontreturn void quick_exit(int exitcode) { int i; const uintptr_t *p; STRACE("quick_exit(%d)", exitcode); + if (SupportsWindows() && GetCurrentProcessId() == __winmainpid) { + for (i = 0; i < 2; ++i) { + SetConsoleMode(GetStdHandle(kConsoleHandles[i]), __ntconsolemode[i]); + } + } if (weaken(fflush)) { weaken(fflush)(0); } diff --git a/libc/runtime/fork-nt.c b/libc/runtime/fork-nt.c index 6704dfb30..c4a641c5f 100644 --- a/libc/runtime/fork-nt.c +++ b/libc/runtime/fork-nt.c @@ -41,6 +41,8 @@ #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" +STATIC_YOINK("_check_sigchld"); + extern int __pid; extern unsigned long long __kbirth; extern unsigned char __data_start[]; /* αpε */ diff --git a/libc/runtime/msync.c b/libc/runtime/msync.c index adcd9a0e9..46f7c147e 100644 --- a/libc/runtime/msync.c +++ b/libc/runtime/msync.c @@ -19,6 +19,7 @@ #include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/macros.internal.h" #include "libc/sysv/consts/msync.h" @@ -34,10 +35,13 @@ * @return 0 on success or -1 w/ errno */ int msync(void *addr, size_t size, int flags) { + int rc; assert(((flags & MS_SYNC) ^ (flags & MS_ASYNC)) || !(MS_SYNC && MS_ASYNC)); if (!IsWindows()) { - return sys_msync(addr, size, flags); + rc = sys_msync(addr, size, flags); } else { - return sys_msync_nt(addr, size, flags); + rc = sys_msync_nt(addr, size, flags); } + STRACE("msync(%p, %'zu, %#x) → %d% m", addr, size, flags, rc); + return rc; } diff --git a/libc/sock/poll-nt.c b/libc/sock/poll-nt.c index 47ebdb80d..dbc3da771 100644 --- a/libc/sock/poll-nt.c +++ b/libc/sock/poll-nt.c @@ -43,8 +43,9 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t ms) { } } for (;;) { - if (cmpxchg(&__interrupted, true, false)) return eintr(); - if (weaken(_check_sigwinch) && weaken(_check_sigwinch)(g_fds.p + 0)) { + if (cmpxchg(&__interrupted, true, false) || + (weaken(_check_sigchld) && weaken(_check_sigchld)()) || + (weaken(_check_sigwinch) && weaken(_check_sigwinch)(g_fds.p + 0))) { return eintr(); } waitfor = MIN(1000, ms); /* for ctrl+c */ diff --git a/libc/stdio/mkostempsm.c b/libc/stdio/mkostempsm.c index ff1b43f33..5d887b4d7 100644 --- a/libc/stdio/mkostempsm.c +++ b/libc/stdio/mkostempsm.c @@ -18,9 +18,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" #include "libc/errno.h" #include "libc/rand/lcg.internal.h" #include "libc/rand/rand.h" +#include "libc/runtime/runtime.h" #include "libc/stdio/temp.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" @@ -34,9 +36,7 @@ int mkostempsmi(char *tpl, int slen, unsigned flags, uint64_t *rando, int mode, int openit(const char *file, int flags, ...)) { size_t len = strlen(tpl); size_t wildlen = strlen(WILDCARD); - if (len < wildlen || slen > len - wildlen) { - return einval(); - } + if (len < wildlen || slen > len - wildlen) return einval(); char *ss = tpl + len - wildlen - slen; assert(memcmp(ss, WILDCARD, wildlen) == 0); flags = (flags & ~(flags & O_ACCMODE)) | O_RDWR | O_CREAT | O_EXCL; @@ -76,6 +76,10 @@ static uint64_t g_mkostemps_reseed; */ dontdiscard int mkostempsm(char *template, int suffixlen, unsigned flags, int mode) { + int fd; if (g_mkostemps_reseed++ % RESEED == 0) g_mkostemps_rand = rand64(); - return mkostempsmi(template, suffixlen, flags, &g_mkostemps_rand, mode, open); + fd = mkostempsmi(template, suffixlen, flags, &g_mkostemps_rand, mode, open); + STRACE("mkostempsm([%#s], %'d, %#x, %#o) → %d% m", template, suffixlen, flags, + mode, fd); + return fd; } diff --git a/libc/stdio/tmpfile.c b/libc/stdio/tmpfile.c index 1bee40c56..c95c65d80 100644 --- a/libc/stdio/tmpfile.c +++ b/libc/stdio/tmpfile.c @@ -18,7 +18,9 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/safemacros.internal.h" #include "libc/calls/calls.h" +#include "libc/calls/strace.internal.h" #include "libc/fmt/fmt.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" @@ -35,7 +37,8 @@ FILE *tmpfile(void) { char *tmp, *sep, tpl[PATH_MAX]; tmp = firstnonnull(getenv("TMPDIR"), kTmpPath); sep = !isempty(tmp) && !endswith(tmp, "/") ? "/" : ""; - if ((snprintf)(tpl, PATH_MAX, "%s%stmp.XXXXXX", tmp, sep) < PATH_MAX) { + if ((snprintf)(tpl, PATH_MAX, "%s%stmp.%s.XXXXXX", tmp, sep, + program_invocation_short_name) < PATH_MAX) { if ((fd = mkostemps(tpl, 0, 0)) != -1) { return fdopen(fd, "w+"); } diff --git a/test/libc/calls/setrlimit_test.c b/test/libc/calls/setrlimit_test.c index 78d3521e9..7cbe59169 100644 --- a/test/libc/calls/setrlimit_test.c +++ b/test/libc/calls/setrlimit_test.c @@ -42,7 +42,7 @@ #define MEM (64 * 1024 * 1024) -char tmpfile[PATH_MAX]; +static char tmpname[PATH_MAX]; void OnSigxcpu(int sig) { ASSERT_EQ(SIGXCPU, sig); @@ -50,7 +50,7 @@ void OnSigxcpu(int sig) { } void OnSigxfsz(int sig) { - unlink(tmpfile); + unlink(tmpname); ASSERT_EQ(SIGXFSZ, sig); _exit(0); } @@ -95,16 +95,16 @@ TEST(setrlimit, testFileSizeLimit) { ASSERT_EQ(0, getrlimit(RLIMIT_FSIZE, &rlim)); rlim.rlim_cur = 1024 * 1024; /* set soft limit to one megabyte */ ASSERT_EQ(0, setrlimit(RLIMIT_FSIZE, &rlim)); - snprintf(tmpfile, sizeof(tmpfile), "%s/%s.%d", + snprintf(tmpname, sizeof(tmpname), "%s/%s.%d", firstnonnull(getenv("TMPDIR"), "/tmp"), program_invocation_short_name, getpid()); - ASSERT_NE(-1, (fd = open(tmpfile, O_RDWR | O_CREAT | O_TRUNC))); + ASSERT_NE(-1, (fd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC))); rngset(junkdata, 512, rand64, -1); for (i = 0; i < 5 * 1024 * 1024 / 512; ++i) { ASSERT_EQ(512, write(fd, junkdata, 512)); } close(fd); - unlink(tmpfile); + unlink(tmpname); _exit(1); } EXPECT_TRUE(WIFEXITED(wstatus)); diff --git a/test/libc/stdio/tmpfile_test.c b/test/libc/stdio/tmpfile_test.c index 5f9039fb0..841255de4 100644 --- a/test/libc/stdio/tmpfile_test.c +++ b/test/libc/stdio/tmpfile_test.c @@ -29,7 +29,7 @@ TEST(tmpfile, test) { FILE *f; mkdir("doge", 0755); setenv("TMPDIR", "doge", true); - f = tmpfile(); + ASSERT_NE(NULL, (f = tmpfile())); EXPECT_NE(-1, fputc('t', f)); EXPECT_NE(-1, fflush(f)); rewind(f); diff --git a/third_party/chibicc/chibicc.c b/third_party/chibicc/chibicc.c index 16e09c9a6..725bb621b 100644 --- a/third_party/chibicc/chibicc.c +++ b/third_party/chibicc/chibicc.c @@ -685,6 +685,7 @@ static void OnCtrlC(int sig, siginfo_t *si, ucontext_t *ctx) { } int chibicc(int argc, char **argv) { + atexit(chibicc_cleanup); sigaction(SIGINT, &(struct sigaction){.sa_sigaction = OnCtrlC}, NULL); for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-cc1")) { diff --git a/tool/net/redbean.c b/tool/net/redbean.c index d18f6f149..d2bec3428 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -506,6 +506,13 @@ static long ParseInt(const char *s) { return strtol(s, 0, 0); } +static void SyncSharedMemory(void) { + if (IsWindows() && !uniprocess) { + LOGIFNEG1( + msync(shared, ROUNDUP(sizeof(struct Shared), FRAMESIZE), MS_ASYNC)); + } +} + static void *FreeLater(void *p) { if (p) { if (++freelist.n > freelist.c) { @@ -1163,6 +1170,7 @@ static void ReportWorkerResources(int pid, struct rusage *ru) { } static void HandleWorkerExit(int pid, int ws, struct rusage *ru) { + SyncSharedMemory(); LockInc(&shared->c.connectionshandled); AddRusage(&shared->children, ru); ReportWorkerExit(pid, ws); @@ -1170,6 +1178,7 @@ static void HandleWorkerExit(int pid, int ws, struct rusage *ru) { if (hasonprocessdestroy) { LuaOnProcessDestroy(pid); } + SyncSharedMemory(); } static void WaitAll(void) { @@ -2670,7 +2679,7 @@ static void LaunchBrowser(const char *path) { sigaction(SIGQUIT, &savequit, 0); sigprocmask(SIG_SETMASK, &savemask, 0); execv(prog, (char *const[]){prog, u, 0}); - _exit(127); + _Exit(127); } while (wait4(pid, &ws, 0, 0) == -1) { CHECK_EQ(EINTR, errno); @@ -6243,7 +6252,7 @@ static bool StreamResponse(char *p) { return true; } -static bool HandleMessageAcutal(void) { +static bool HandleMessageActual(void) { int rc; char *p; if ((rc = ParseHttpMessage(&msg, inbuf.p, amtread)) != -1) { @@ -6300,8 +6309,9 @@ static bool HandleMessageAcutal(void) { static bool HandleMessage(void) { bool r; ishandlingrequest = true; - r = HandleMessageAcutal(); + r = HandleMessageActual(); ishandlingrequest = false; + SyncSharedMemory(); return r; } @@ -6812,6 +6822,7 @@ static wontreturn void ExitWorker(void) { MemDestroy(); CheckForMemoryLeaks(); } + SyncSharedMemory(); _Exit(0); }