It was added by this commit

commit 9568600ab19ef7da61ae7de4b43f1fc075556102
Author: Gregory Nutt <gn...@nuttx.org>
Date:   Wed Oct 4 15:22:27 2017 -0600

    Squashed commit of the following:

        This commit backs out most of commit
b4747286b19d3b15193b2a5e8a0fe48fa0a8638c.  That change was added because
sem_wait() would sometimes cause cancellation points inappropriated.  But
with these recent changes, nxsem_wait() is used instead and it is not a
cancellation point.

        In the OS, all calls to sem_wait() changed to nxsem_wait().
 nxsem_wait() does not return errors via errno so each place where
nxsem_wait() is now called must not examine the errno variable.

        In all OS functions (not libraries), change sem_wait() to
nxsem_wait().  This will prevent the OS from creating bogus cancellation
points and from modifying the per-task errno variable.

        sched/semaphore:  Add the function nxsem_wait().  This is a new
internal OS interface.  It is functionally equivalent to sem_wait() except
that (1) it is not a cancellation point, and (2) it does not set the
per-thread errno value on return.


пт, 27 трав. 2022 р. о 16:57 Petro Karashchenko <
petro.karashche...@gmail.com> пише:

> 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