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

чт, 26 трав. 2022 р. о 22:49 Gregory Nutt <spudan...@gmail.com> пише:

> 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