Yes and no. I've posted a code from sem_wait that checks if a cancellation
is pending but cannot be performed due to the nesting level,
so enter_cancellation_point will just increment the nested count
and leave_cancellation_point will just decrement it. In this case ECANCELED
will be returned by sem_wait and _SEM_WAIT() will be called again
endlessly because cancelation nesting counted will just increment and
decrement.

Best regards,
Petro

пт, 27 трав. 2022 р. о 16:23 Gregory Nutt <spudan...@gmail.com> пише:

> On 5/27/2022 12:52 AM, Petro Karashchenko wrote:
> > Hi,
> >
> > Ok. That makes sense. But there is a strane code in sem_wait:
> >
> >    if (enter_cancellation_point())
> >      {
> > #ifdef CONFIG_CANCELLATION_POINTS
> >        /* If there is a pending cancellation, then do not perform
> >         * the wait.  Exit now with ECANCELED.
> >         */
> >
> >        errcode = ECANCELED;
> >        goto errout_with_cancelpt;
> > #endif
> >      }
> >
> > This code in conjunction with "while ((ret = _SEM_WAIT(sem)) < 0)" seems
> to
> > be a pure "deadlock" (endless loop) in case if _SEM_WAIT is defined to
> > sem_wait. Or am I missing something?
> > This is of course when sem_wait is called while the task entered the
> > cancellation point already.
> >
> > Best regards,
> > Petro
>
> "while ((ret = _SEM_WAIT(sem)) < 0)" is not an endless loop.
>
> ECANCEL is handled just like EINTR:  For EINTR, when the signal is
> received, _SEM_WAIT wakes up and returns -EINTR.  If _SEM_WAIT is called
> again, it does not remember that the thread was signaled; it does not
> return -EINTR again but behaves normally and waits for the semaphore.
>
> ECANCEL works the same:  When a thread is canceled, _SEM_WAIT wakes up
> and return -ECANCELED.  If _SEM_WAIT is called it again, it does not
> remember that the thread was canceled; it does not return -ECANCELED
> again but behaves normally and waits for the semaphore.
>
> So there is no infinite loop.
>
>
>

Reply via email to