aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2020-12-30 00:10:11 -0500
committerRuss Cox <rsc@swtch.com>2020-12-30 00:12:14 -0500
commitb3a20a96eb2b91a5b0b8a8fb506e20a2fb50ebe8 (patch)
tree0cebec89bb62594af9c5310e1ba99a4dee65b51b
parent5b37d9126474864b5299426e27b2af37fcc96dd0 (diff)
downloadplan9port-b3a20a96eb2b91a5b0b8a8fb506e20a2fb50ebe8.tar.gz
plan9port-b3a20a96eb2b91a5b0b8a8fb506e20a2fb50ebe8.tar.bz2
plan9port-b3a20a96eb2b91a5b0b8a8fb506e20a2fb50ebe8.zip
libthread: add threadmaybackground
Programs that want to background themselves now need to define threadmaybackground returning 1. This avoids a confusing (to people and debuggers) extra parent process for all the threaded programs that will never want to background themselves.
-rw-r--r--include/thread.h7
-rw-r--r--man/man3/thread.334
-rw-r--r--src/cmd/9pfuse/main.c6
-rw-r--r--src/cmd/9pserve.c6
-rw-r--r--src/cmd/auth/factotum/main.c6
-rw-r--r--src/cmd/auth/ssh-agent.c6
-rw-r--r--src/cmd/fossil/fossil.c6
-rw-r--r--src/cmd/import.c6
-rw-r--r--src/cmd/ndb/dns.c6
-rw-r--r--src/cmd/plumb/plumber.c6
-rw-r--r--src/cmd/smugfs/main.c6
-rw-r--r--src/cmd/upas/fs/fs.c6
-rw-r--r--src/cmd/upas/nfs/main.c6
-rw-r--r--src/cmd/venti/srv/venti.c6
-rw-r--r--src/lib9p/ramfs.c6
-rw-r--r--src/libthread/bg.c7
-rw-r--r--src/libthread/daemonize.c12
-rw-r--r--src/libthread/mkfile1
-rw-r--r--src/libthread/thread.c2
19 files changed, 120 insertions, 21 deletions
diff --git a/include/thread.h b/include/thread.h
index c01cd516..8c800829 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -1,7 +1,7 @@
#ifndef _THREAD_H_
#define _THREAD_H_ 1
#if defined(__cplusplus)
-extern "C" {
+extern "C" {
#endif
AUTOLIB(thread)
@@ -15,6 +15,7 @@ void threadexits(char *);
void threadexitsall(char *);
void threadsetname(char*, ...);
void threadsetstate(char*, ...);
+void threadneedbackground(void);
char *threadgetname(void);
int threadyield(void);
int threadidle(void);
@@ -60,6 +61,8 @@ void **threaddata(void);
void threadmain(int argc, char *argv[]);
extern int mainstacksize;
+int threadmaybackground(void);
+
/*
* channel communication
*/
@@ -180,7 +183,7 @@ int threadspawnl(int[3], char*, ...);
Channel* threadwaitchan(void);
/*
- * alternate interface to threadwaitchan - don't use both!
+ * alternate interface to threadwaitchan - don't use both!
*/
Waitmsg* procwait(int pid);
diff --git a/man/man3/thread.3 b/man/man3/thread.3
index 6c6b4602..02e4c868 100644
--- a/man/man3/thread.3
+++ b/man/man3/thread.3
@@ -33,6 +33,7 @@ threadintgrp,
threadkill,
threadkillgrp,
threadmain,
+threadmaybackground,
threadnotify,
threadid,
threadpid,
@@ -80,6 +81,7 @@ struct Alt {
.ft L
.ta \w'\fLChannel* 'u +4n +4n +4n +4n
void threadmain(int argc, char *argv[])
+int threadmaybackground(void)
int mainstacksize
int proccreate(void (*fn)(void*), void *arg, uint stacksize)
int threadcreate(void (*fn)(void*), void *arg, uint stacksize)
@@ -171,7 +173,7 @@ initialized to the desired value
.BR 1024 ).
When using the
.I pthread
-library,
+library,
.B mainstacksize
is ignored, as is the stack size argument to
.BR proccreate :
@@ -185,7 +187,7 @@ executes
.I fn(arg)
on a stack of size
.IR stacksize .
-Thread stacks are allocated in shared memory, making it valid to pass
+Thread stacks are allocated in shared memory, making it valid to pass
pointers to stack variables between threads and procs.
.I Proccreate
creates a new proc, and inside that proc creates
@@ -207,7 +209,7 @@ returning the id of the created thread.
.\" in
.\" .IR rforkflag .)
.\" .I Proccreate
-.\" is identical to
+.\" is identical to
.\" .I procrfork
.\" with
.\" .I rforkflag
@@ -238,6 +240,14 @@ When the last thread in
.IR threadmain 's
proc exits, the program will appear to its parent to have exited.
The remaining procs will still run together, but as a background program.
+This functionality can only be relied upon if the program defines a function
+.I threadmaybackground
+returning a non-zero result.
+Programs that do not define such a
+.I threadmaybackground
+will crash instead should the last thread in
+.IR threadmain 's
+proc exit leaving behind other running procs.
.PP
The threads in a proc are coroutines, scheduled nonpreemptively
in a round-robin fashion.
@@ -341,18 +351,18 @@ Also for debugging,
threads have a string state associated with them.
.I Threadsetstate
sets the state string.
-There is no
+There is no
.IR threadgetstate ;
since the thread scheduler resets the state to
.B Running
-every time it runs the thread,
+every time it runs the thread,
it is only useful for debuggers to inspect the state.
.PP
.I Threaddata
returns a pointer to a per-thread pointer
that may be modified by threaded programs for
per-thread storage.
-Similarly,
+Similarly,
.I procdata
returns a pointer to a per-proc pointer.
.PP
@@ -398,11 +408,11 @@ response.
.I Threadexecl
and
.I threadexec
-will duplicate
+will duplicate
(see
.MR dup (3) )
the three file descriptors in
-.I fd
+.I fd
onto standard input, output, and error for the external program
and then close them in the calling thread.
Beware of code that sets
@@ -467,9 +477,9 @@ operation blocks until the corresponding
operation occurs and
.IR "vice versa" .
.IR Chancreate
-allocates a new channel
+allocates a new channel
for messages of size
-.I elsize
+.I elsize
and with a buffer holding
.I nel
messages.
@@ -645,7 +655,7 @@ from the main proc before any other procs have been created.
To create new processes, use
.IR proccreate .
.\" .PP
-.\" It is safe to use
+.\" It is safe to use
.\" .IR rfork
.\" (see
.\" .IR fork (3))
@@ -663,7 +673,7 @@ To create new processes, use
.\" .BR RFCENVG.
.\" (To create new processes, use
.\" .I proccreate
-.\" and
+.\" and
.\" .IR procrfork .)
.\" As mentioned above,
.\" the thread library depends on all procs being in the
diff --git a/src/cmd/9pfuse/main.c b/src/cmd/9pfuse/main.c
index 69d1ad75..4fa330a0 100644
--- a/src/cmd/9pfuse/main.c
+++ b/src/cmd/9pfuse/main.c
@@ -98,6 +98,12 @@ usage(void)
void fusereader(void*);
void watchfd(void*);
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char **argv)
{
diff --git a/src/cmd/9pserve.c b/src/cmd/9pserve.c
index 255bcbb2..e26eef14 100644
--- a/src/cmd/9pserve.c
+++ b/src/cmd/9pserve.c
@@ -137,6 +137,12 @@ usage(void)
threadexitsall("usage");
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
uchar vbuf[128];
extern int _threaddebuglevel;
void
diff --git a/src/cmd/auth/factotum/main.c b/src/cmd/auth/factotum/main.c
index b3ace12c..6dfc2a40 100644
--- a/src/cmd/auth/factotum/main.c
+++ b/src/cmd/auth/factotum/main.c
@@ -20,6 +20,12 @@ usage(void)
threadexitsall("usage");
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char *argv[])
{
diff --git a/src/cmd/auth/ssh-agent.c b/src/cmd/auth/ssh-agent.c
index c3b0c7ef..e944e390 100644
--- a/src/cmd/auth/ssh-agent.c
+++ b/src/cmd/auth/ssh-agent.c
@@ -90,6 +90,12 @@ usage(void)
threadexitsall("usage");
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char **argv)
{
diff --git a/src/cmd/fossil/fossil.c b/src/cmd/fossil/fossil.c
index 002e8510..c5672c86 100644
--- a/src/cmd/fossil/fossil.c
+++ b/src/cmd/fossil/fossil.c
@@ -59,6 +59,12 @@ readCmdPart(char *file, char ***pcmd, int *pncmd)
*pncmd = ncmd;
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char* argv[])
{
diff --git a/src/cmd/import.c b/src/cmd/import.c
index 0be2f5b6..7da70966 100644
--- a/src/cmd/import.c
+++ b/src/cmd/import.c
@@ -51,6 +51,12 @@ fatal(char *fmt, ...)
threadexitsall("fatal");
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char *argv[])
{
diff --git a/src/cmd/ndb/dns.c b/src/cmd/ndb/dns.c
index cb317052..723989b9 100644
--- a/src/cmd/ndb/dns.c
+++ b/src/cmd/ndb/dns.c
@@ -121,6 +121,12 @@ checkaddress(void)
fprint(2, "warning: announce mismatch %s %s\n", udpaddr, tcpaddr);
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char *argv[])
{
diff --git a/src/cmd/plumb/plumber.c b/src/cmd/plumb/plumber.c
index c99282f0..5ead2e93 100644
--- a/src/cmd/plumb/plumber.c
+++ b/src/cmd/plumb/plumber.c
@@ -26,6 +26,12 @@ makeports(Ruleset *rules[])
addport(rules[i]->port);
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char *argv[])
{
diff --git a/src/cmd/smugfs/main.c b/src/cmd/smugfs/main.c
index e1c2745f..31c9a752 100644
--- a/src/cmd/smugfs/main.c
+++ b/src/cmd/smugfs/main.c
@@ -51,6 +51,12 @@ smuglogin(void)
printerrors = 0;
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char **argv)
{
diff --git a/src/cmd/upas/fs/fs.c b/src/cmd/upas/fs/fs.c
index dc6ff3ba..32968e67 100644
--- a/src/cmd/upas/fs/fs.c
+++ b/src/cmd/upas/fs/fs.c
@@ -155,6 +155,12 @@ notifyf(void *a, char *s)
noted(NDFLT);
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char *argv[])
{
diff --git a/src/cmd/upas/nfs/main.c b/src/cmd/upas/nfs/main.c
index c72a4849..68ae141b 100644
--- a/src/cmd/upas/nfs/main.c
+++ b/src/cmd/upas/nfs/main.c
@@ -26,6 +26,12 @@ usage(void)
threadexitsall("usage");
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char **argv)
{
diff --git a/src/cmd/venti/srv/venti.c b/src/cmd/venti/srv/venti.c
index 1725537a..67fda91e 100644
--- a/src/cmd/venti/srv/venti.c
+++ b/src/cmd/venti/srv/venti.c
@@ -23,6 +23,12 @@ usage(void)
threadexitsall("usage");
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char *argv[])
{
diff --git a/src/lib9p/ramfs.c b/src/lib9p/ramfs.c
index b7a07c7d..7cf6489d 100644
--- a/src/lib9p/ramfs.c
+++ b/src/lib9p/ramfs.c
@@ -125,6 +125,12 @@ usage(void)
threadexitsall("usage");
}
+int
+threadmaybackground(void)
+{
+ return 1;
+}
+
void
threadmain(int argc, char **argv)
{
diff --git a/src/libthread/bg.c b/src/libthread/bg.c
new file mode 100644
index 00000000..2edbc0e4
--- /dev/null
+++ b/src/libthread/bg.c
@@ -0,0 +1,7 @@
+#include "threadimpl.h"
+
+int
+threadmaybackground(void)
+{
+ return 0;
+}
diff --git a/src/libthread/daemonize.c b/src/libthread/daemonize.c
index 387d1527..f994ffe1 100644
--- a/src/libthread/daemonize.c
+++ b/src/libthread/daemonize.c
@@ -8,7 +8,7 @@
#undef wait
static int sigpid;
-static int threadpassfd;
+static int threadpassfd = -1;
static int gotsigchld;
static void
@@ -163,9 +163,9 @@ _threadsetupdaemonize(void)
void
_threaddaemonize(void)
{
- if(threadpassfd >= 0){
- write(threadpassfd, "0", 1);
- close(threadpassfd);
- threadpassfd = -1;
- }
+ if(threadpassfd < 0)
+ sysfatal("threads in main proc exited w/o threadmaybackground");
+ write(threadpassfd, "0", 1);
+ close(threadpassfd);
+ threadpassfd = -1;
}
diff --git a/src/libthread/mkfile b/src/libthread/mkfile
index 8a77a316..eca4f4df 100644
--- a/src/libthread/mkfile
+++ b/src/libthread/mkfile
@@ -4,6 +4,7 @@ SYSOFILES=`{sh ./sysofiles.sh}
LIB=libthread.a
OFILES=\
$SYSOFILES\
+ bg.$O\
channel.$O\
daemonize.$O\
exec.$O\
diff --git a/src/libthread/thread.c b/src/libthread/thread.c
index 65e65194..7151e875 100644
--- a/src/libthread/thread.c
+++ b/src/libthread/thread.c
@@ -844,7 +844,7 @@ main(int argc, char **argv)
// Easier to just run in pthread-per-thread mode.
pthreadperthread = 1;
#endif
- if(strstr(opts, "nodaemon") == nil && getenv("NOLIBTHREADDAEMONIZE") == nil)
+ if(threadmaybackground() && strstr(opts, "nodaemon") == nil && getenv("NOLIBTHREADDAEMONIZE") == nil)
_threadsetupdaemonize();
threadargc = argc;