commit b3a20a96eb2b91a5b0b8a8fb506e20a2fb50ebe8 from: Russ Cox date: Wed Dec 30 05:12:14 2020 UTC 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. commit - 5b37d9126474864b5299426e27b2af37fcc96dd0 commit + b3a20a96eb2b91a5b0b8a8fb506e20a2fb50ebe8 blob - c01cd5166a40360c20712ac806afa4a5e69bedf5 blob + 8c80082926c22d787a71a030cacf390518812fa4 --- include/thread.h +++ 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); blob - 6c6b4602219ea8402fdb46eb7f07c8176d014f81 blob + 02e4c8686f181b9b700df591be57e63b9a227c0b --- man/man3/thread.3 +++ 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 cr 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 blob - 69d1ad75d8853d8ce96529b69703c90c8d436849 blob + 4fa330a081aad33de1a434a13ae86905651b7bc4 --- src/cmd/9pfuse/main.c +++ src/cmd/9pfuse/main.c @@ -97,6 +97,12 @@ usage(void) void fusereader(void*); void watchfd(void*); + +int +threadmaybackground(void) +{ + return 1; +} void threadmain(int argc, char **argv) blob - 255bcbb25244b6276cc3f973f1d084947f765e7b blob + e26eef1465effe3d5073a73dd2620e145453002b --- src/cmd/9pserve.c +++ src/cmd/9pserve.c @@ -135,6 +135,12 @@ usage(void) fprint(2, "usage: 9pserve [-lnv] [-A aname afid] [-c addr] [-M msize] address\n"); fprint(2, "\treads/writes 9P messages on stdin/stdout\n"); threadexitsall("usage"); +} + +int +threadmaybackground(void) +{ + return 1; } uchar vbuf[128]; blob - b3ace12c41e976d0e1ea2bf7889b0073ad6eb874 blob + 6dfc2a400be50ae1ae2199b46b8ea348ca7f8095 --- src/cmd/auth/factotum/main.c +++ 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[]) { blob - c3b0c7ef35373bf992059fbadd170269971183e3 blob + e944e3901f0b7b023d952c7c80c90ebdbc57f511 --- src/cmd/auth/ssh-agent.c +++ src/cmd/auth/ssh-agent.c @@ -88,6 +88,12 @@ usage(void) { fprint(2, "usage: 9 ssh-agent [-D] [factotum]\n"); threadexitsall("usage"); +} + +int +threadmaybackground(void) +{ + return 1; } void blob - 002e851037b7c0bcd4a2612273d524c17eb588ac blob + c5672c8697b52e9505d2cbb22a609c8cd09c88f7 --- src/cmd/fossil/fossil.c +++ 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[]) { blob - 0be2f5b6f9e28a3fd7e662fa56cd260b0e9ac28c blob + 7da70966e51fbc2180fb99415be748d0f5af3770 --- src/cmd/import.c +++ src/cmd/import.c @@ -49,6 +49,12 @@ fatal(char *fmt, ...) fprint(2, "%s: %s\n", argv0 ? argv0 : "", buf); threadexitsall("fatal"); +} + +int +threadmaybackground(void) +{ + return 1; } void blob - cb3170529338cc65d956250ab577d4966e223ed7 blob + 723989b96c058eabac92cb65e6aeaab2617413cd --- src/cmd/ndb/dns.c +++ src/cmd/ndb/dns.c @@ -119,6 +119,12 @@ checkaddress(void) t = strchr(tcpaddr, '!'); if(u && t && strcmp(u, t) != 0) fprint(2, "warning: announce mismatch %s %s\n", udpaddr, tcpaddr); +} + +int +threadmaybackground(void) +{ + return 1; } void blob - c99282f02da0c4a939fb49ae3ec32c49b18fc5a5 blob + 5ead2e931307ae5347c86d96203da057914b68b9 --- src/cmd/plumb/plumber.c +++ 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[]) { blob - e1c2745f6549ad4038c27a13c3976f5689e1c12c blob + 31c9a752b6d25de09f2e70e6f33ffd230a89d243 --- src/cmd/smugfs/main.c +++ src/cmd/smugfs/main.c @@ -51,6 +51,12 @@ smuglogin(void) printerrors = 0; } +int +threadmaybackground(void) +{ + return 1; +} + void threadmain(int argc, char **argv) { blob - dc6ff3ba6f7ccf3308d5819f1284af496b492717 blob + 32968e67ef72b298fa88d9952c62c19ef3974059 --- src/cmd/upas/fs/fs.c +++ src/cmd/upas/fs/fs.c @@ -153,6 +153,12 @@ notifyf(void *a, char *s) if(strncmp(s, "interrupt", 9) == 0) noted(NCONT); noted(NDFLT); +} + +int +threadmaybackground(void) +{ + return 1; } void blob - c72a48494e13b795abdbd9a2cf69e2f1695e1b1c blob + 68ae141b54f79f6fa39f30ae33cf9083465283c4 --- src/cmd/upas/nfs/main.c +++ 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) { blob - 1725537a2bc1838c8d43bd788088f035a596e297 blob + 67fda91e1687030b44c5ef1a570aeb359938761b --- src/cmd/venti/srv/venti.c +++ src/cmd/venti/srv/venti.c @@ -21,6 +21,12 @@ usage(void) fprint(2, "usage: venti [-Ldrs] [-a address] [-B blockcachesize] [-c config] " "[-C lumpcachesize] [-h httpaddress] [-I indexcachesize] [-W webroot]\n"); threadexitsall("usage"); +} + +int +threadmaybackground(void) +{ + return 1; } void blob - b7a07c7d00758d5e45189265ac0dd947ee81fcd0 blob + 7cf6489d57d28598bf6791d8d20c0aa07a50bd8c --- src/lib9p/ramfs.c +++ src/lib9p/ramfs.c @@ -125,6 +125,12 @@ usage(void) threadexitsall("usage"); } +int +threadmaybackground(void) +{ + return 1; +} + void threadmain(int argc, char **argv) { blob - /dev/null blob + 2edbc0e48d4ae6f8009692de502874e09722b7c2 (mode 644) --- /dev/null +++ src/libthread/bg.c @@ -0,0 +1,7 @@ +#include "threadimpl.h" + +int +threadmaybackground(void) +{ + return 0; +} blob - 387d1527280d0a6b584e26851e35f3d622616d53 blob + f994ffe159da4095a37a661be3f1d6b0bdbd711f --- src/libthread/daemonize.c +++ 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; } blob - 8a77a316175189b619f9b0b15c60bdb78acdc40a blob + eca4f4df445f7bfdcef6e2923386fa295ddc49ee --- src/libthread/mkfile +++ src/libthread/mkfile @@ -4,6 +4,7 @@ SYSOFILES=`{sh ./sysofiles.sh} LIB=libthread.a OFILES=\ $SYSOFILES\ + bg.$O\ channel.$O\ daemonize.$O\ exec.$O\ blob - 65e651949b2fe0e783ab745f5f11f70ad11b4d39 blob + 7151e8756f26afb856e83107529bcb7c0a1451dc --- src/libthread/thread.c +++ 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;