trestore old plan 9 property that when the last thread exits the main proc, the remaining program ends up in the background and the program appears to have exited. - plan9port - [fork] Plan 9 from user space (HTM) git clone git://src.adamsgaard.dk/plan9port (DIR) Log (DIR) Files (DIR) Refs (DIR) README (DIR) LICENSE --- (DIR) commit 1d2533d0101fd1721ab26837485c0b094205c3bd (DIR) parent 07bda1263eb4e319e9d8b278e81d75f67a417b66 (HTM) Author: rsc <devnull@localhost> Date: Tue, 28 Dec 2004 22:36:24 +0000 restore old plan 9 property that when the last thread exits the main proc, the remaining program ends up in the background and the program appears to have exited. Diffstat: M src/libthread/FreeBSD.c | 7 +++++++ M src/libthread/Linux.c | 5 +++++ M src/libthread/daemonize.c | 21 ++++++++++++++------- M src/libthread/pthread.c | 5 +++++ M src/libthread/thread.c | 5 ++++- M src/libthread/threadimpl.h | 1 + 6 files changed, 36 insertions(+), 8 deletions(-) --- (DIR) diff --git a/src/libthread/FreeBSD.c b/src/libthread/FreeBSD.c t@@ -346,6 +346,13 @@ _pthreadinit(void) signal(SIGUSR2, sigusr2handler); } +void +_threadpexit(void) +{ + _exit(0); +} + + /* * FreeBSD 4 and earlier needs the context functions. */ (DIR) diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c t@@ -348,3 +348,8 @@ _pthreadinit(void) signal(SIGUSR2, sigusr2handler); } +void +_threadpexit(void) +{ + _exit(0); +} (DIR) diff --git a/src/libthread/daemonize.c b/src/libthread/daemonize.c t@@ -9,10 +9,13 @@ static int threadpassfd; static void child(void) { - int status; - if(wait(&status) == sigpid) - if(WIFEXITED(status)) - _exit(WEXITSTATUS(status)); + int status, pid; + pid = wait(&status); + if(pid < 0) + fprint(2, "wait: %r\n"); + else if(WIFEXITED(status)) + _exit(WEXITSTATUS(status)); +print("pid %d if %d %d\n", pid, WIFEXITED(status), WEXITSTATUS(status)); _exit(97); } t@@ -51,6 +54,7 @@ _threadsetupdaemonize(void) if(fcntl(p[0], F_SETFD, 1) < 0 || fcntl(p[1], F_SETFD, 1) < 0) sysfatal("passer pipe pipe fcntl: %r"); + signal(SIGCHLD, sigpass); switch(pid = fork()){ case -1: sysfatal("passer fork: %r"); t@@ -58,6 +62,7 @@ _threadsetupdaemonize(void) close(p[1]); break; case 0: + signal(SIGCHLD, SIG_DFL); rfork(RFNOTEG); close(p[0]); threadpassfd = p[1]; t@@ -89,7 +94,9 @@ _threadsetupdaemonize(void) void threaddaemonize(void) { - write(threadpassfd, "0", 1); - close(threadpassfd); - threadpassfd = -1; + if(threadpassfd >= 0){ + write(threadpassfd, "0", 1); + close(threadpassfd); + threadpassfd = -1; + } } (DIR) diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c t@@ -132,3 +132,8 @@ threadexitsall(char *msg) exits(msg); } +void +_threadpexit(void) +{ + pthread_exit(0); +} (DIR) diff --git a/src/libthread/thread.c b/src/libthread/thread.c t@@ -476,6 +476,8 @@ main(int argc, char **argv) { Proc *p; + argv0 = argv[0]; + _threadsetupdaemonize(); threadargc = argc; t@@ -503,7 +505,8 @@ main(int argc, char **argv) mainstacksize = 65536; _threadcreate(p, threadmainstart, nil, mainstacksize); scheduler(p); - return 0; /* not reached */ + threaddaemonize(); + _threadpexit(); } /* (DIR) diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h t@@ -122,3 +122,4 @@ extern int _threadspawn(int*, char*, char**); extern int _runthreadspawn(int*, char*, char**); extern void _threadsetupdaemonize(void); extern void _threaddodaemonize(char*); +extern void _threadpexit(void);