Summary:ASTERISK-24154: [patch]PTHREAD_MUTEX_INITIALIZER should not be assumed to be recursive mutex
Reporter:Timo Teräs (fabled)Labels:patch
Date Opened:2014-08-04 08:25:28Date Closed:
Versions:12.4.0 13.18.5 Frequency of
Environment:Attachments:( 0) musl-mutex-init.patch
Description:Currently the build system recognizes if PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP is available, and uses it only if detected. If it is not available, PTHREAD_MUTEX_INITIALIZER is used instead. Only on Solaris and BSD, the code revers using constructors to call pthread_mutex_init with proper attributes to create recursive mutex.

This logic is wrong. PTHREAD_MUTEX_INITIALIZER is not guaranteed to create recursive mutex. Please do that assumption only on GLIBC or other C-libraries where this is a known fact.

Current code is broken assumably on non-GLIBC systems not explicitly listed. One notable example is musl c-library based Linux systems.
Comments:By: Timo Teräs (fabled) 2014-08-04 08:26:08.448-0500

Example fix.

By: Joshua C. Colp (jcolp) 2017-12-18 09:43:38.250-0600

Is this still a problem such that it can't be used under musl? There is at least one other person who is doing so already.

By: Timo Teräs (fabled) 2017-12-29 02:09:25.719-0600

Situation is still the same. musl abides to POSIX:

"In cases where default mutex attributes are appropriate, the macro PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes. The effect shall be equivalent to dynamic initialization by a call to pthread_mutex_init() with parameter attr specified as NULL, except that no error checks are performed."

"The default value of the type attribute is PTHREAD_MUTEX_DEFAULT."

"If the mutex type is PTHREAD_MUTEX_DEFAULT, the behavior of pthread_mutex_lock() may correspond to one of the three other standard mutex types as described in the table above. If it does not correspond to one of those three, the behavior is undefined for the cases marked "
The table says that DEFAULT mutex has undefined behaviour for "Relock" (=recursive locking) and "Unlock When Not Owner".

POSIX is clear that the default initializer is not reliable on making mutex a recursive one.

Perhaps the other person is using patched musl, having my patch, or not yet experienced the dead-lock problems caused by having wrong type of mutex.

I also check musl c-library source code today, and the DEFAULT mutex is still consider to be "NORMAL" mutex which cannot be used recursively.