nxsem_wait() is not a cancellation point.   There are no cancellation
points within the OS, onl nsy at the application interface.  So sem_wait()
is a cancellation point;  It nxsem_wait() will  not.  nxsem_wait()  will
not cause the thread calling nxsem_wait() but will return ECANCELED.

In these cases, ECANCELED should normally be returned with no other
action.  Normally, the cancellation  will occur later, just before the
"real" use interface returns.  For example, if the application calls read()
and the driver read method receives ECANCELED from nxsem_wait(), it should
just return that error upstream.  read() is a cancellation point and when
read() finally returns to the caller,the thread will be canceled.

There is some relevant discussion here:
https://cwiki.apache.org/confluence/display/NUTTX/Cancellation+Points



On Thu, May 26, 2022 at 8:16 AM Petro Karashchenko <
petro.karashche...@gmail.com> wrote:

> Hi,
>
> This question arises during the review of one PRs. Indeed, it seems that
> ECANCELED should never be returned to the app
> because leave_cancellation_point() should terminate the task; however there
> are quite a few places in code that check ECANCELED returned by semaphore.
> Those are:
> - mm_takesemaphore: DEBUGASSERT(ret == -EINTR || ret == -ECANCELED);
> - modlib_registry_lock: DEBUGASSERT(_SEM_ERRNO(ret) == EINTR ||
> _SEM_ERRNO(ret) == ECANCELED);
> - dns_semtake: DEBUGASSERT(errcode == EINTR || errcode == ECANCELED);
> - lib_take_semaphore: DEBUGASSERT(_SEM_ERRNO(ret) == EINTR ||SEM_ERRNO(ret)
> == ECANCELED);
> - lib_stream_semtake: DEBUGASSERT(_SEM_ERRNO(ret) == EINTR ||SEM_ERRNO(ret)
> == ECANCELED);
> - get_base62: DEBUGASSERT(_SEM_ERRNO(ret) == EINTR || _SEM_ERRNO(ret) ==
> ECANCELED);
> - tz_semtake: DEBUGASSERT(errcode == EINTR || errcode == ECANCELED);
> - nxf_list_lock: DEBUGASSERT(errorcode == EINTR || errorcode == ECANCELED);
> - nxf_cache_lock: DEBUGASSERT(errorcode == EINTR || errorcode ==
> ECANCELED);
> - nxmu_semtake: DEBUGASSERT(_SEM_ERRNO(ret) == EINTR || _SEM_ERRNO(ret) ==
> ECANCELED);
> - and few other places
>
> The _SEM_WAIT can be either nxsem_wait or sem_wait, so maybe those checks
> are targeting the nxsem_wait case and not sem_wait.
>
> Maybe someone can educate me on that because in all those use cases code is
> spinning on while ((ret = _SEM_WAIT(sem)) < 0).
>
> Best regards,
> Petro
>
> чт, 26 трав. 2022 р. о 16:42 Gregory Nutt <spudan...@gmail.com> пише:
>
> >
> > > I haven't looked at that code in a long time.  But I believe that the
> > > ECANCELED error is never returned to the application.  If a thread is
> > > canceled, that error is caught by the cancellation point logic and the
> > > thread is terminated before it ever returns to the application.
> > >
> > > If cancellation points are not enabled then the ECANCELED error shoul
> > > never be generated.
> >
> > There are only a couple of places where ECANCELED can be returned to the
> > caller (aio_cancel(), timerfd_create(), a probably others.
> >
> > I would not be surprised if there are places in the code where ECANCELED
> > could be returned to the application inappropriately. But these would
> > all be errors and should be fixed.  No testing has been done to see if
> > we can force and erroneous ECANCELED return.
> >
> > For example, what would happen if you enable cancellation points, but
> > disable cancellation, then call a function that requires cancellation
> > support?  The correct result is that the cancellation attempt should
> > fail and the thread should continue running.
> >
> > Returning EINTR would be wrong in any case.
> >
> >
> >
>

Reply via email to