Re: POSIX: ECANCELED returned by sem_wait
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.
Re: POSIX: ECANCELED returned by sem_wait
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 пише: > 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. > > >
Re: POSIX: ECANCELED returned by sem_wait
It was added by this commit commit 9568600ab19ef7da61ae7de4b43f1fc075556102 Author: Gregory Nutt 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 пише: > >> 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. >> >> >>
Re: POSIX: ECANCELED returned by sem_wait
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 _SEM_WAIT maps to either nxsem_wait or sem_wait. The cancellation point applies only to sem_wait. This should not happen in reality because OS cancellation points never call other functions that are cancellation points. That is because the cancellation point is inside the OS and must never use the application-oriented interfaces (like sem_wait) but only internal OS interfaces like nxsem_wait. In that case, cancellation points will never be nested. I had it on my To-Do list for a long time to remove the nested cancellation point support. It should never occur and the logic that you are referring to should be replaced with an assertion. I thought that there was an Issue covering this, but I don't see it.
Re: POSIX: ECANCELED returned by sem_wait
Ok. Let's fill the issue and clean-up sem_wait as well as I met that code in sem_wait only, so other places should never return ECANCELED. пт, 27 трав. 2022 р. о 17:07 Gregory Nutt пише: > > > 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 > > _SEM_WAIT maps to either nxsem_wait or sem_wait. The cancellation point > applies only to sem_wait. > > This should not happen in reality because OS cancellation points never > call other functions that are cancellation points. That is because the > cancellation point is inside the OS and must never use the > application-oriented interfaces (like sem_wait) but only internal OS > interfaces like nxsem_wait. In that case, cancellation points will > never be nested. > > I had it on my To-Do list for a long time to remove the nested > cancellation point support. It should never occur and the logic that > you are referring to should be replaced with an assertion. I thought > that there was an Issue covering this, but I don't see it. > > >