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