eclipse-iceoryx / eclipse-iceoryx/iceoryx
QNX behavior for robust mutex differs from POSIX standard
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 492
- Avg merge
- 18h 57m
- Merged PRs (30d)
- 1
Description
## Required information
**Operating system:**
QNX 7.1 (and maybe other versions)
**Compiler version:**
Compiler independent
**Observed result or behaviour:**
A mutex which was set to robust with `pthread_mutexattr_setrobust` fails in `pthread_mutex_lock` when the owning thread died before releasing the mutex.
For more details, see https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/p/pthread_mutexattr_setrobust.html
And the quote:
```
If the process containing the owning thread of a robust mutex terminates while holding the mutex lock, the
next thread that acquires the mutex is notified about the termination by the return value EOWNERDEAD
from the locking function.
```
So the robust mutex failure is only detected when a process holding the mutex dies and not the thread.
**Expected result or behaviour:**
The mutex should behave like described in the posix standard, see https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_getrobust.html
And the quote:
```
If the process containing the owning thread of a robust mutex terminates while holding the mutex lock, the
next thread that acquires the mutex shall be notified about the termination by the return value [EOWNERDEAD]
from the locking function.
If the owning thread of a robust mutex terminates while holding the mutex lock, the
next thread that attempts to acquire the mutex may be notified about the termination by the return
value [EOWNERDEAD].
```
It states that if a thread owning a lock terminates other threads which acquire the lock should be informed.
Expected behavior is that `pthread_mutex_lock` detects the failure and sets the `errno` to `EOWNERDEAD`.
**Conditions where it occurred / Performed steps:**
Create a posix thread, lock the robust mutex in that thread and terminate the thread. If another thread would like to acquire that mutex it fails with the errno `EINVAL`.
According to the posix standard (https://pubs.opengroup.org/onlinepubs/009604499/functions/pthread_mutex_lock.html) the following cases are possible for `EINVAL`.
* The mutex was created with the protocol attribute having the value PTHREAD_PRIO_PROTECT and the calling thread's priority is higher than the mutex's current priority ceiling.
* The value specified by mutex does not refer to an initialized mutex object.
Here again the QNX behavior differs (https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/p/pthread_mutex_lock.html) and states that `EINVAL` can be caused by::
* The mutex was created with a protocol attribute of PTHREAD_PRIO_PROTECT, and the calling thread's priority is higher than the mutex's current priority ceiling.
* The mutex is invalid, is destroyed, or the process that's the target of the event associated with the mutex has died (see [SyncMutexEvent()](https://www.qnx.com/developers/docs/7.1/com.qnx.doc.neutrino.lib_ref/topic/s/syncmutexevent.html)).
(QNX Neutrino extension; QNX Neutrino 7.0.1 or later)
* You're using safe shared mutexes (see the -s option for [procnto](https://www.qnx.com/developers/docs/7.1/com.qnx.doc.neutrino.utilities/topic/p/procnto.html)), and you tried to lock a PTHREAD_PRIO_INHERIT mutex whose owner isn't known to the kernel and that the locking thread claims is from a different process.
Contributor guide
Research direction
No repository file or test is named. Start by reproducing the QNX pthread_mutex_lock scenario described in the report and trace the mutex handling entry point; done means a thread-owned robust mutex reports EOWNERDEAD rather than EINVAL after its owner terminates.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100