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

@ -15,6 +15,7 @@ void threadexits(char *);
void threadexitsall(char *); void threadexitsall(char *);
void threadsetname(char*, ...); void threadsetname(char*, ...);
void threadsetstate(char*, ...); void threadsetstate(char*, ...);
void threadneedbackground(void);
char *threadgetname(void); char *threadgetname(void);
int threadyield(void); int threadyield(void);
int threadidle(void); int threadidle(void);
@ -60,6 +61,8 @@ void **threaddata(void);
void threadmain(int argc, char *argv[]); void threadmain(int argc, char *argv[]);
extern int mainstacksize; extern int mainstacksize;
int threadmaybackground(void);
/* /*
* channel communication * channel communication
*/ */

View file

@ -33,6 +33,7 @@ threadintgrp,
threadkill, threadkill,
threadkillgrp, threadkillgrp,
threadmain, threadmain,
threadmaybackground,
threadnotify, threadnotify,
threadid, threadid,
threadpid, threadpid,
@ -80,6 +81,7 @@ struct Alt {
.ft L .ft L
.ta \w'\fLChannel* 'u +4n +4n +4n +4n .ta \w'\fLChannel* 'u +4n +4n +4n +4n
void threadmain(int argc, char *argv[]) void threadmain(int argc, char *argv[])
int threadmaybackground(void)
int mainstacksize int mainstacksize
int proccreate(void (*fn)(void*), void *arg, uint stacksize) int proccreate(void (*fn)(void*), void *arg, uint stacksize)
int threadcreate(void (*fn)(void*), void *arg, uint stacksize) int threadcreate(void (*fn)(void*), void *arg, uint stacksize)
@ -238,6 +240,14 @@ When the last thread in
.IR threadmain 's .IR threadmain 's
proc exits, the program will appear to its parent to have exited. proc exits, the program will appear to its parent to have exited.
The remaining procs will still run together, but as a background program. 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 .PP
The threads in a proc are coroutines, scheduled nonpreemptively The threads in a proc are coroutines, scheduled nonpreemptively
in a round-robin fashion. in a round-robin fashion.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -121,6 +121,12 @@ checkaddress(void)
fprint(2, "warning: announce mismatch %s %s\n", udpaddr, tcpaddr); fprint(2, "warning: announce mismatch %s %s\n", udpaddr, tcpaddr);
} }
int
threadmaybackground(void)
{
return 1;
}
void void
threadmain(int argc, char *argv[]) threadmain(int argc, char *argv[])
{ {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -125,6 +125,12 @@ usage(void)
threadexitsall("usage"); threadexitsall("usage");
} }
int
threadmaybackground(void)
{
return 1;
}
void void
threadmain(int argc, char **argv) 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 #undef wait
static int sigpid; static int sigpid;
static int threadpassfd; static int threadpassfd = -1;
static int gotsigchld; static int gotsigchld;
static void static void
@ -163,9 +163,9 @@ _threadsetupdaemonize(void)
void void
_threaddaemonize(void) _threaddaemonize(void)
{ {
if(threadpassfd >= 0){ if(threadpassfd < 0)
sysfatal("threads in main proc exited w/o threadmaybackground");
write(threadpassfd, "0", 1); write(threadpassfd, "0", 1);
close(threadpassfd); close(threadpassfd);
threadpassfd = -1; threadpassfd = -1;
}
} }

View file

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

View file

@ -844,7 +844,7 @@ main(int argc, char **argv)
// Easier to just run in pthread-per-thread mode. // Easier to just run in pthread-per-thread mode.
pthreadperthread = 1; pthreadperthread = 1;
#endif #endif
if(strstr(opts, "nodaemon") == nil && getenv("NOLIBTHREADDAEMONIZE") == nil) if(threadmaybackground() && strstr(opts, "nodaemon") == nil && getenv("NOLIBTHREADDAEMONIZE") == nil)
_threadsetupdaemonize(); _threadsetupdaemonize();
threadargc = argc; threadargc = argc;