On 6/17/22 09:06, andrey100100...@gmail.com wrote: > В Пт, 17/06/2022 в 08:11 -0600, Jacob Moody пишет: >> On 6/17/22 07:46, Thaddeus Woskowiak wrote: >>> I believe threadnotify() should be called from threadmain() to >>> properly register the handler in the rendez group >> >> This is incorrect, according to thread(2): >> >> "The thread library depends on all procs >> being in the same rendezvous group" > > > From sleep(2): > > Alarm causes an alarm note (see notify(2)) to be sent to the > invoking process after the number of milliseconds given by > the argument. > > Mean to be sent only to the invoking process, NOT to the process group.
Yes this is correct, If I implied otherwise I apologize. My point with pointing out that excerpt is that groups likely had nothing to do with this. >> >> The issue here is that your note handler has to call noted, >> you are returning from the handler without actually resuming the >> program. >> You either need to call noted(NCONT) to resume execution or >> noted(NDFLT) >> to stop execution. >> >> An excerpt from notify(2): >> >> "A notification handler must finish either by exiting the >> program or by calling noted; if the handler returns the >> behavior is undefined and probably erroneous." >> >> So you are indeed observing undefined behavior. >> > > With: > > ------------------------------------ > static int > handler_alarm(void *, char *msg) > { > if(strstr(msg, "alarm")){ > noted(NCONT); > return 1; > } > > return 0; > } > ------------------------------------ > result the same: > > cpu% 6.out | grep end | wc -l > 33 > > > And noted(NCONT) may be needed, when process recieved many (2 and more) > notes at once. > > May be something wrong with interrupted an incomplete system call? You _always_ should call either noted(NCONT) or noted(NDFLT). But you are correct in that this wasn't the exact issue. I poked around with the code a bit. I rewrote it to just use fork(), and I got all 80 "end" messages. So I suspected libthread had some arbitrary limit: #define NFN 33 #define ERRLEN 48 typedef struct Note Note; struct Note { Lock inuse; Proc *proc; /* recipient */ char s[ERRMAX]; /* arg2 */ }; static Note notes[128]; static Note *enotes = notes+nelem(notes); static int (*onnote[NFN])(void*, char*); static int onnotepid[NFN]; static Lock onnotelock; int threadnotify(int (*f)(void*, char*), int in) { int i, topid; int (*from)(void*, char*), (*to)(void*, char*); 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; break; } unlock(&onnotelock); return i<NFN; } That #define NFN 33 seems like the culprit. Looks like if you checked the return value of threadnotify you would have seen your notes handler was not registered. Now as to why this limit is so low, I am not sure. Perhaps it should be bumped up. Thanks, moody ------------------------------------------ 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tfa6823048ad90a21-M687ef3adb4df6c21a188e7e1 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription