В Пн, 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

Reply via email to