В Пн, 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-M3802ed594c69b660a4210973 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription