mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-27 15:52:28 +00:00
Improve posix_spawn() some more
This commit is contained in:
parent
6430e474b4
commit
00084577a3
18 changed files with 301 additions and 293 deletions
|
@ -180,6 +180,8 @@ int main(int argc, char *argv[]) {
|
|||
_Exit(1);
|
||||
}
|
||||
|
||||
__threaded = 1;
|
||||
|
||||
ASSERT_EQ(0, pthread_mutexattr_init(&attr));
|
||||
ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL));
|
||||
ASSERT_EQ(0, pthread_mutex_init(&mu, &attr));
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
|
@ -219,6 +221,44 @@ TEST(posix_spawn, agony) {
|
|||
}
|
||||
}
|
||||
|
||||
void EmptySigHandler(int sig) {
|
||||
}
|
||||
|
||||
TEST(posix_spawn, etxtbsy) {
|
||||
if (IsWindows()) return; // can't deliver signals between processes
|
||||
if (IsXnu()) return; // they don't appear impacted by this race condition
|
||||
if (IsNetbsd()) return; // they don't appear impacted by this race condition
|
||||
if (IsOpenbsd()) return; // they don't appear impacted by this race condition
|
||||
int ws, me, pid, thief;
|
||||
char *prog = "./life.com";
|
||||
char *args[] = {prog, 0};
|
||||
char *envs[] = {0};
|
||||
sigset_t ss, old;
|
||||
testlib_extract("/zip/life.com", prog, 0755);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
sigemptyset(&ss);
|
||||
sigaddset(&ss, SIGUSR1);
|
||||
sigprocmask(SIG_BLOCK, &ss, &old);
|
||||
sigdelset(&ss, SIGUSR1);
|
||||
ASSERT_SYS(0, 3, open(prog, O_RDWR));
|
||||
signal(SIGUSR1, EmptySigHandler);
|
||||
me = getpid();
|
||||
if (!(thief = fork())) {
|
||||
ASSERT_SYS(0, 0, kill(me, SIGUSR1));
|
||||
ASSERT_SYS(EINTR, -1, sigsuspend(&ss));
|
||||
_Exit(0);
|
||||
}
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
EXPECT_SYS(EINTR, -1, sigsuspend(&ss));
|
||||
EXPECT_EQ(ETXTBSY, posix_spawn(&pid, prog, NULL, NULL, args, envs));
|
||||
EXPECT_EQ(0, kill(thief, SIGUSR1));
|
||||
EXPECT_EQ(thief, wait(&ws));
|
||||
ASSERT_EQ(0, ws);
|
||||
sigprocmask(SIG_SETMASK, &old, 0);
|
||||
unassert(!errno);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ForkExecveWait(const char *prog) {
|
||||
|
|
|
@ -100,16 +100,6 @@ o/$(MODE)/test/libc/stdio/posix_spawn_test.com.dbg: \
|
|||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/test/libc/stdio/wut_test.com.dbg: \
|
||||
$(TEST_LIBC_STDIO_DEPS) \
|
||||
o/$(MODE)/test/libc/stdio/wut_test.o \
|
||||
o/$(MODE)/test/libc/stdio/stdio.pkg \
|
||||
o/$(MODE)/tool/build/echo.com.zip.o \
|
||||
$(LIBC_TESTMAIN) \
|
||||
$(CRT) \
|
||||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
$(TEST_LIBC_STDIO_OBJS): private \
|
||||
DEFAULT_CCFLAGS += \
|
||||
-fno-builtin
|
||||
|
|
|
@ -169,7 +169,7 @@ void *CondWaitDeferredWorker(void *arg) {
|
|||
pthread_setcancelstate(PTHREAD_CANCEL_DEFERRED, 0);
|
||||
ASSERT_EQ(0, pthread_mutex_lock(&mu));
|
||||
ASSERT_EQ(ECANCELED, pthread_cond_timedwait(&cv, &mu, 0));
|
||||
__builtin_trap();
|
||||
abort();
|
||||
}
|
||||
|
||||
TEST(pthread_cancel, condDeferredWait_reacquiresMutex) {
|
||||
|
|
|
@ -95,7 +95,7 @@ void *Worker(void *arg) {
|
|||
sem_t **s = arg;
|
||||
struct timespec ts;
|
||||
ASSERT_SYS(0, 0, clock_gettime(CLOCK_REALTIME, &ts));
|
||||
ts.tv_sec += 1;
|
||||
ts.tv_sec += 10;
|
||||
ASSERT_SYS(0, 0, sem_post(s[0]));
|
||||
ASSERT_SYS(0, 0, sem_timedwait(s[1], &ts));
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue