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

Reply via email to