On Sat, Oct 23, 2021 at 05:47:58PM +0200, Mark Kettenis wrote:
> > Date: Sat, 23 Oct 2021 17:29:36 +0200
> > From: Claudio Jeker <[email protected]>
> > 
> > The sys___thrsigdivert code can be simplified a bit. It is possible to
> > set the error before the loop and then have the loop exit after polling
> > for pending signals. IMO the results looks nicer than what we have now.
> > 
> > OK?
> 
> That does not look right:
> 
>   The function sigtimedwait() behaves the same as sigwaitinfo() except
>   that if none of the signals specified by set are pending,
>   sigtimedwait() waits for the time interval specified in the timespec
>   structure referenced by timeout. If the timespec structure pointed
>   to by timeout is zero-valued and if none of the signals specified by
>   set are pending, then sigtimedwait() returns immediately with an
>   error. If timeout is the NULL pointer, the behaviour is unspecified.
> 
> So you need to check for signals first.

The code does the check first. It just sets the error before doing the
pending signal check. If a signal is pending the error is reset to 0 and
the function returns. Else it will break out of the loop with the error
and not hit the tsleep.
 
> The current code looks fine to me.
> 
> 
> > Index: kern/kern_sig.c
> > ===================================================================
> > RCS file: /cvs/src/sys/kern/kern_sig.c,v
> > retrieving revision 1.286
> > diff -u -p -r1.286 kern_sig.c
> > --- kern/kern_sig.c 23 Oct 2021 14:56:55 -0000      1.286
> > +++ kern/kern_sig.c 23 Oct 2021 15:15:21 -0000
> > @@ -1761,7 +1761,6 @@ sys___thrsigdivert(struct proc *p, void 
> >     sigset_t mask = SCARG(uap, sigmask) &~ sigcantmask;
> >     siginfo_t si;
> >     uint64_t nsecs = INFSLP;
> > -   int timeinvalid = 0;
> >     int error = 0;
> >  
> >     memset(&si, 0, sizeof(si));
> > @@ -1774,12 +1773,21 @@ sys___thrsigdivert(struct proc *p, void 
> >             if (KTRPOINT(p, KTR_STRUCT))
> >                     ktrreltimespec(p, &ts);
> >  #endif
> > -           if (!timespecisvalid(&ts))
> > -                   timeinvalid = 1;
> > -           else
> > +           if (timespecisvalid(&ts)) {
> >                     nsecs = TIMESPEC_TO_NSEC(&ts);
> > +           } else {
> > +                   /*
> > +                    * per-POSIX, delay this error until
> > +                    * after checking for signals
> > +                    */
> > +                   error = EINVAL;
> > +           }
> >     }
> >  
> > +   /* per-POSIX, return immediatly if timeout is zero-valued */
> > +   if (nsecs == 0)
> > +           error = EAGAIN;
> > +
> >     dosigsuspend(p, p->p_sigmask &~ mask);
> >     for (;;) {
> >             si.si_signo = cursig(p);
> > @@ -1791,13 +1799,6 @@ sys___thrsigdivert(struct proc *p, void 
> >                             break;
> >                     }
> >             }
> > -
> > -           /* per-POSIX, delay this error until after the above */
> > -           if (timeinvalid)
> > -                   error = EINVAL;
> > -           /* per-POSIX, return immediatly if timeout is zero-valued */
> > -           if (nsecs == 0)
> > -                   error = EAGAIN;
> >  
> >             if (error != 0)
> >                     break;
> > 
> > 

-- 
:wq Claudio

Reply via email to