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. > > > > > > > > > > > >