On Wed, Mar 18, 2020 at 10:11 AM Gregory Nutt <spudan...@gmail.com> wrote:
> >> There is one issue we have to be careful about:  pthread
> >> _mutex_timedlock():  It needs the signal in order to wake up and return
> >> from the wait. pthread_mutex_lock() just calls pthread_mutex_timedlock()
> >> with and time value of NULL.  So it is this NULL argument that is passed
> >> must cause different behaviors:  Non-NULL: interruptible and NULL:
> >> noninterruptible.
>
> Actually, there is a problem with that.  The above approach would not
> work because it would break cancellation of threads via signals.
> nxsem_wait_uninterruptible() cannot be used in this case because it
> ignores cancallations:
>
> include/nuttx/semaphore.h:
>
>     544 static inline int nxsem_wait_uninterruptible(FAR sem_t *sem)
>     545 {
>     546   int ret;
>     547
>     548   do
>     549     {
>     550       /* Take the semaphore (perhaps waiting) */
>     551
>     552       ret = nxsem_wait(sem);
>     553     }
>     554   while (ret == -EINTR || ret == -ECANCELED);
>     555
>     556   return ret;
>     557 }
>
> -ECANCELED must wake up the thread so that it can die gracefully.  If it
> continues to loop on nxsem_wait() then cancellation is broken.

So we have to back up a step: NULL or non-NULL timeout argument both
should use interruptible nxsem_wait as they are already doing today.

To get the behavior POSIX specifies ("If a signal is delivered to a
thread waiting for a mutex, upon return from the signal handler the
thread resumes waiting for the mutex as if it was not interrupted.")
would require additional handling, such as (I'm guessing) checking the
cause of the wake-up and looping if necessary. Admittedly I don't know
enough about the subject and the internals to propose a specific
solution yet.

Nathan

Reply via email to