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