It's cleaner to use channels with separate io and timer threads that do their syscalls via ioproc; this one doesn't require any changes to libthread:
https://gist.github.com/9nut/aaa9b9b6a22d69996b75ccdc6e615c61 On Mon, Jun 20, 2022 at 8:57 AM <andrey100100...@gmail.com> wrote: > > В Пн, 20/06/2022 в 05:59 +0000, adr пишет: > > On Mon, 20 Jun 2022, adr wrote: > > > But I have something in mind for a case like > > > this, when all the processes are going to use the same handler > > > (that's why I was asking). Let me play with it a litle before I > > > share it. > > > > Ok, the idea is this: If in is bigger than zero in > > threadnotify(int (*f)(void*, char*), int in), the handler is register > > for the calling process. If in is 0, then the handler is cleared > > for the calling process. If in is -1, the handler is register for > > all processes and if in is less than -1, it is cleared for all > > processes (expect for those who have already registered it for > > themselves). > > > > Now back to your example, as all the processes are going to use the > > same handler, > > you just have to register it once in threadmain: > > > > #include <u.h> > > #include <libc.h> > > #include <thread.h> > > > > static int > > handler_alarm(void *, char *msg) > > { > > if(strstr(msg, "alarm")) > > return 1; > > return 0; > > } > > > > static void > > proc_udp(void *) > > { > > char resp[512]; > > char req[] = "request"; > > int fd; > > if((fd = dial("udp!185.157.221.201!5678", nil, nil, nil)) >= > > 0){ > > if(write(fd, req, strlen(req)) == strlen(req)){ > > fprint(1, "start\n"); > > alarm(2000); > > read(fd, resp, sizeof(resp)); > > alarm(0); > > fprint(1, "end\n"); > > } > > close(fd); > > } > > threadexits(nil); > > } > > > > int mainstacksize = 5242880; > > > > void > > threadmain(int argc, char *argv[]) > > { > > threadnotify(handler_alarm, -1); > > for(int i = 0; i < 80; i++) > > proccreate(proc_udp, nil, 10240); > > sleep(5000); > > threadexitsall(nil); > > } > > Now, > > ; ./5.out | grep end | wc -l > > 80 > > > > Are you happy Andrej? > > > Yes. Thank you very much! It's working! > > How convenient it is to use - more experiments are needed. > > > > > > adr. > > > > /sys/src/libthread/sched.c: > > [...] > > if(t == nil){ > > _threaddebug(DBGSCHED, "all threads gone; > > exiting"); > > cancelnotes(p->pid); > > _schedexit(p); > > } > > [...] > > /sys/src/libthread/note.c > > [...] > > int > > threadnotify(int (*f)(void*, char*), int in) > > { > > int i, frompid, topid; > > int (*from)(void*, char*), (*to)(void*, char*); > > > > if(in && in>-2){ > > from = nil; > > frompid = 0; > > to = f; > > topid = (in == -1)? -1 : _threadgetproc()->pid; > > lock(&onnotelock); > > for(i=0; i<NFN; i++) > > if(onnote[i]==to && onnotepid[i]==topid){ > > unlock(&onnotelock); > > return i<NFN; > > } > > unlock(&onnotelock); > > }else{ > > from = f; > > frompid = (in < -1)? -1 : _threadgetproc()->pid; > > to = nil; > > topid = 0; > > } > > lock(&onnotelock); > > for(i=0; i<NFN; i++) > > if(onnote[i]==from && onnotepid[i]==frompid){ > > onnote[i] = to; > > onnotepid[i] = topid; > > break; > > } > > unlock(&onnotelock); > > return i<NFN; > > } > > > > void > > cancelnotes(int pid) > > { > > int i; > > > > lock(&onnotelock); > > for(i=0; i<NFN; i++) > > if(onnotepid[i] == pid){ > > onnote[i] = nil; > > onnotepid[i] = 0; > > } > > unlock(&onnotelock); > > return; > > } > > > > static void > > delayednotes(Proc *p, void *v) > > { > > int i; > > Note *n; > > int (*fn)(void*, char*); > > > > if(!p->pending) > > return; > > > > p->pending = 0; > > for(n=notes; n<enotes; n++){ > > if(n->proc == p){ > > for(i=0; i<NFN; i++){ > > if((onnotepid[i]!=p->pid && > > onnotepid[i]!=-1) || (fn = onnote[i])==nil) > > continue; > > if((*fn)(v, n->s)) > > break; > > [...] > > /sys/include/thread.h > > [...] > > void cancelnotes(int pid); > > [...] > > > > Regards, > Andrej ------------------------------------------ 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tfa6823048ad90a21-M99eed0ec152c6bbad2332628 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription