From: andrey100100100@gmail.com
To: 9fans@9fans.net
Subject: Re: [9fans] syscall silently kill processes
Date: Tue, 28 Jun 2022 22:09:34 +0300 [thread overview]
Message-ID: <d190838f714190b55bfd07f41b3ca52bb0e11631.camel@gmail.com> (raw)
In-Reply-To: <87cff69b-4b82-8466-a34f-13c7eda24fc9@SDF.ORG>
В Вт, 28/06/2022 в 15:28 +0000, adr пишет:
> Andrey, if you want to use different note handlers per process (with
> a big
> number of processes) using libthread, this may be helpful.
>
> The idea is this:
>
> An array of handlers for all processes which can be changed by all
> processes.
> When a note is received by a process, this array takes priority.
>
> An array of pointers to structures of the type
>
> struct Onnote
> {
> int pid;
> int (*fn[NFN])(void*, char*);
> };
>
> initially of size PPCHUNK (I set it to 100, experiment with that),
> but it can grow if necessary (but not shrink, I think this would
> be overkilling).
>
> These structures are allocated the first time a process record a
> handler and freed when the process exits (or by calling
> threadcancelnotes(), note that this function can free other
> processes'
> function handlers, maybe should be better to make some restrictions)
>
> The use of "in" in threadnotify(int (*f)(void*, char*), int in) is:
>
> in > 0 : set the handler for the calling process.
> in == 0 : clear the handler for the calling process.
> in == -1 : clear the handler for all processes (except those who has
> registered it already for themselves).
> in < -1 : set the handler for all processes.
>
> There is no use of threadnotify with "in < 0" in /sys/src, so nothing
> is broken.
>
> As you are using 9front and they are serving their sources with
> 9p, here is a diff to their sources. I haven't compiled it in
> 9front, though. Note that if you want to compile the system with
> this changes, you have to eliminate the copy of note.c at
> /sys/src/cmd/execnet (it seems that note.c was added afterwards as
> I thought).
>
> I haven't test it too much, this has been more like a time-destroyer
> pastime.
>
> adr
> --- /tmp/main.c
> +++ /sys/src/libthread/main.c
> @@ -28,6 +28,10 @@
> _qlockinit(_threadrendezvous);
> _sysfatal = _threadsysfatal;
> __assert = _threadassert;
> + onnote = mallocz(PPCHUNK*sizeof(uintptr), 1);
> + if(!onnote)
> + sysfatal("Malloc of size %d failed: %r",
> PPCHUNK*sizeof(uintptr));
> + onnotesize = PPCHUNK;
> notify(_threadnote);
> if(mainstacksize == 0)
> mainstacksize = 8*1024;
> --- /tmp/note.c
> +++ /sys/src/libthread/note.c
> @@ -5,9 +5,9 @@
>
> int _threadnopasser;
>
> -#define NFN 33
> #define ERRLEN 48
> typedef struct Note Note;
> +
> struct Note
> {
> Lock inuse;
> @@ -17,62 +17,155 @@
>
> static Note notes[128];
> static Note *enotes = notes+nelem(notes);
> -static int (*onnote[NFN])(void*, char*);
> -static int onnotepid[NFN];
> +Onnote **onnote;
> +int onnotesize;
> +static int (*onnoteall[NFN])(void*, char*);
> static Lock onnotelock;
>
> int
> threadnotify(int (*f)(void*, char*), int in)
> {
> - int i, topid;
> - int (*from)(void*, char*), (*to)(void*, char*);
> + int i, j;
>
> - if(in){
> - from = nil;
> - to = f;
> - topid = _threadgetproc()->pid;
> - }else{
> - from = f;
> - to = nil;
> - topid = 0;
> - }
> lock(&onnotelock);
> - for(i=0; i<NFN; i++)
> - if(onnote[i]==from){
> - onnote[i] = to;
> - onnotepid[i] = topid;
> +
> + /* add note for all processes */
> + if(in < -1){
> + for(i=0; i<NFN; i++)
> + if(onnoteall[i] == f){
> + unlock(&onnotelock);
> + return 1;
> + }
> + for(i=0; i<NFN; i++)
> + if(onnoteall[i] == nil){
> + onnoteall[i] = f;
> + break;
> + }
> + unlock(&onnotelock);
> + return i<NFN;
> + }
> +
> + /* remove note for all processes */
> + if(in == -1){
> + for(i=0; i<NFN; i++)
> + if(onnoteall[i] == f){
> + onnoteall[i] = nil;
> + break;
> + }
> + unlock(&onnotelock);
> + return i<NFN;
> + }
> +
> + /* remove note for current process */
> + if(!in){
> + for(i=0; i<onnotesize; i++){
> + if(onnote[i]!=nil && onnote[i]-
> >pid==_threadgetproc()->pid){
> + for(j=0; j<NFN; j++){
> + if(onnote[i]->fn[j] == f){
> + onnote[i]->fn[j] = 0;
> + break;
> + }
> + }
> + unlock(&onnotelock);
> + return j<NFN;
> + }
> + }
> + unlock(&onnotelock);
> + return i<onnotesize;
> + }
> +
> + /* add note for current process */
> + for(i=0; i<onnotesize; i++)
> + if(onnote[i] && onnote[i]->pid==_threadgetproc()-
> >pid)
> + break;
> +
> + /* process has already a slot */
> + if(i < onnotesize){
> + for(j=0; j<NFN; j++){
> + if(onnote[i]->fn[j] == nil){
> + onnote[i]->fn[j] = f;
> + break;
> + }
> + }
> + unlock(&onnotelock);
> + return j<NFN;
> +
> + }
> +
> + for(i=0; i<onnotesize; i++)
> + if(!onnote[i])
> + break;
> +
> + /* there is no free slot */
> + if(i == onnotesize){
> + onnotesize += PPCHUNK;
> + onnote = realloc(onnote, onnotesize*sizeof(uintptr));
> + if(!onnote){
> + unlock(&onnotelock);
> + sysfatal("Malloc of size %d failed: %r",
> onnotesize*sizeof(uintptr));
> + }
> + memset(onnote+i+1, 0, PPCHUNK-1);
> + }
> +
> + onnote[i]=mallocz(sizeof(Onnote), 1);
> + if(!onnote[i]){
> + unlock(&onnotelock);
> + sysfatal("Malloc of size %d failed: %r",
> sizeof(Onnote));
> + }
> + onnote[i]->pid = _threadgetproc()->pid;
> + onnote[i]->fn[0] = f;
> + unlock(&onnotelock);
> + return 1;
> +}
> +
> +void
> +threadcancelnotes(int pid)
> +{
> + int i;
> +
> + lock(&onnotelock);
> + for(i=0; i<onnotesize; i++)
> + if(onnote[i] && onnote[i]->pid==pid){
> + free(onnote[i]);
> + onnote[i] = nil;
> break;
> }
> unlock(&onnotelock);
> - return i<NFN;
> + return;
> }
>
> static void
> delayednotes(Proc *p, void *v)
> {
> - int i;
> + int i, j, all;
> Note *n;
> - char s[ERRMAX];
> - int (*fn)(void*, char*);
> + int (*f)(void*, char*);
>
> if(!p->pending)
> return;
>
> p->pending = 0;
> + all = j = 0;
> for(n=notes; n<enotes; n++){
> if(n->proc == p){
> - strcpy(s, n->s);
> - n->proc = nil;
> - unlock(&n->inuse);
> -
> - for(i=0; i<NFN; i++){
> - if(onnotepid[i]!=p->pid || (fn =
> onnote[i])==nil)
> - continue;
> - if((*fn)(v, s))
> - break;
> + for(i=0; i<NFN; i++)
> + if(f=onnoteall[i])
> + if((*f)(v, n->s)){
> + all = 1;
> + break;
> + }
> + if(!all){
> + for(i=0; i<onnotesize; i++)
> + if(onnote[i] && onnote[i]-
> >pid==p->pid){
> + for(j=0; j<NFN; j++)
> +
> if(f=onnote[i]->fn[j])
> +
> if((*f)(v, n->s))
> +
> break;
> + break;
> + }
> }
> - if(i==NFN){
> - _threaddebug(DBGNOTE, "Unhandled note
> %s, proc %p", n->s, p);
> + if(!all && (i==onnotesize || j==NFN)){
> + _threaddebug(DBGNOTE, "Unhandled note
> %s, proc %p\n", n->s, p);
> if(v != nil)
> noted(NDFLT);
> else if(strncmp(n->s, "sys:", 4)==0)
> @@ -79,6 +172,8 @@
> abort();
> threadexitsall(n->s);
> }
> + n->proc = nil;
> + unlock(&n->inuse);
> }
> }
> }
> @@ -94,7 +189,7 @@
> noted(NDFLT);
>
> if(_threadexitsallstatus){
> - _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'",
> _threadexitsallstatus);
> + _threaddebug(DBGNOTE, "Threadexitsallstatus =
> '%s'\n", _threadexitsallstatus);
> _exits(_threadexitsallstatus);
> }
>
> --- /tmp/sched.c
> +++ /sys/src/libthread/sched.c
> @@ -157,6 +157,7 @@
> t = runthread(p);
> if(t == nil){
> _threaddebug(DBGSCHED, "all threads gone;
> exiting");
> + threadcancelnotes(p->pid);
> unlinkproc(p);
> _schedexit(p); /* frees proc */
> }
> --- /tmp/thread.h
> +++ /sys/include/thread.h
> @@ -97,6 +97,7 @@
> void threadkillgrp(int); /* kill threads in group */
> void threadmain(int argc, char *argv[]);
> int threadnotify(int (*f)(void*, char*), int in);
> +void threadcancelnotes(int pid);
> int threadid(void);
> int threadpid(int);
> int threadsetgrp(int); /* set thread group, return
> old */
> --- /tmp/threadimpl.h
> +++ /sys/src/libthread/threadimpl.h
> @@ -192,3 +192,15 @@
> #define _threaddebug(flag, ...)
> if((_threaddebuglevel&(flag))==0){}else _threadprint(__VA_ARGS__)
>
> #define ioproc_arg(io, type) (va_arg((io)->arg, type))
> +
> +#define PPCHUNK 100
> +#define NFN 33
> +typedef struct Onnote Onnote;
> +struct Onnote
> +{
> + int pid;
> + int (*fn[NFN])(void*, char*);
> +};
> +extern Onnote **onnote;
> +extern int onnotesize;
> +void _threadnote(void*, char*);
> ------------------------------------------
Thanks for the patch.
Regards,
Andrej
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/Tfa6823048ad90a21-Mb89a47f334b083f180f89f9a
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
next prev parent reply other threads:[~2022-06-28 19:09 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-17 9:37 andrey100100100
2022-06-17 13:46 ` Thaddeus Woskowiak
2022-06-17 14:11 ` Jacob Moody
2022-06-17 14:39 ` Thaddeus Woskowiak
2022-06-17 15:06 ` andrey100100100
2022-06-17 16:08 ` Skip Tavakkolian
2022-06-17 16:11 ` Skip Tavakkolian
2022-06-17 16:16 ` Skip Tavakkolian
2022-06-17 17:42 ` adr
2022-06-17 16:11 ` Jacob Moody
2022-06-17 18:48 ` andrey100100100
2022-06-17 19:28 ` Jacob Moody
2022-06-17 21:15 ` adr
2022-06-18 6:40 ` andrey100100100
2022-06-18 8:37 ` adr
2022-06-18 9:22 ` adr
2022-06-18 12:53 ` Jacob Moody
2022-06-18 22:03 ` andrey100100100
2022-06-19 5:54 ` adr
2022-06-19 6:13 ` Jacob Moody
2022-06-18 22:22 ` andrey100100100
2022-06-18 16:57 ` andrey100100100
2022-06-19 2:40 ` adr
2022-06-19 5:01 ` adr
2022-06-19 8:52 ` andrey100100100
2022-06-19 10:32 ` adr
2022-06-19 11:40 ` andrey100100100
2022-06-19 12:01 ` andrey100100100
2022-06-19 15:10 ` andrey100100100
2022-06-19 16:41 ` adr
2022-06-19 21:22 ` andrey100100100
2022-06-19 21:26 ` andrey100100100
2022-06-20 4:41 ` adr
2022-06-20 5:39 ` andrey100100100
2022-06-20 5:59 ` adr
2022-06-20 15:56 ` andrey100100100
2022-06-20 22:29 ` Skip Tavakkolian
2022-06-21 7:07 ` andrey100100100
2022-06-21 11:26 ` adr
2022-06-21 13:03 ` andrey100100100
2022-06-21 13:22 ` adr
2022-06-28 15:28 ` adr
2022-06-28 16:43 ` ori
2022-06-28 18:19 ` adr
2022-06-28 18:28 ` adr
2022-06-28 19:09 ` andrey100100100 [this message]
2022-06-28 19:42 ` adr
2022-06-29 13:14 ` adr
2022-06-21 13:47 ` andrey100100100
2022-06-21 7:22 ` adr
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d190838f714190b55bfd07f41b3ca52bb0e11631.camel@gmail.com \
--to=andrey100100100@gmail.com \
--cc=9fans@9fans.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).