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.
This commit is contained in:
Russ Cox 2020-12-30 00:10:11 -05:00
parent 5b37d91264
commit b3a20a96eb
19 changed files with 120 additions and 21 deletions

View file

@ -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);

View file

@ -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

View file

@ -98,6 +98,12 @@ usage(void)
void fusereader(void*);
void watchfd(void*);
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char **argv)
{

View file

@ -137,6 +137,12 @@ usage(void)
threadexitsall("usage");
}
int
threadmaybackground(void)
{
return 1;
}
uchar vbuf[128];
extern int _threaddebuglevel;
void

View file

@ -20,6 +20,12 @@ usage(void)
threadexitsall("usage");
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char *argv[])
{

View file

@ -90,6 +90,12 @@ usage(void)
threadexitsall("usage");
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char **argv)
{

View file

@ -59,6 +59,12 @@ readCmdPart(char *file, char ***pcmd, int *pncmd)
*pncmd = ncmd;
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char* argv[])
{

View file

@ -51,6 +51,12 @@ fatal(char *fmt, ...)
threadexitsall("fatal");
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char *argv[])
{

View file

@ -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[])
{

View file

@ -26,6 +26,12 @@ makeports(Ruleset *rules[])
addport(rules[i]->port);
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char *argv[])
{

View file

@ -51,6 +51,12 @@ smuglogin(void)
printerrors = 0;
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char **argv)
{

View file

@ -155,6 +155,12 @@ notifyf(void *a, char *s)
noted(NDFLT);
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char *argv[])
{

View file

@ -26,6 +26,12 @@ usage(void)
threadexitsall("usage");
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char **argv)
{

View file

@ -23,6 +23,12 @@ usage(void)
threadexitsall("usage");
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char *argv[])
{

View file

@ -125,6 +125,12 @@ usage(void)
threadexitsall("usage");
}
int
threadmaybackground(void)
{
return 1;
}
void
threadmain(int argc, char **argv)
{

7
src/libthread/bg.c Normal file
View file

@ -0,0 +1,7 @@
#include "threadimpl.h"
int
threadmaybackground(void)
{
return 0;
}

View file

@ -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;
}

View file

@ -4,6 +4,7 @@ SYSOFILES=`{sh ./sysofiles.sh}
LIB=libthread.a
OFILES=\
$SYSOFILES\
bg.$O\
channel.$O\
daemonize.$O\
exec.$O\

View file

@ -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;