EtcPal  0.4.1
ETC Platform Abstraction Layer (EtcPal)
View other versions:
recursive_mutex (Recursive Mutexes)

Overview

Mutual-exclusion (mutex) objects with recursion support.

#include "etcpal/recursive_mutex.h"

WARNING: Recursive mutexes are rarely necessary for new code. They are often used to retrofit thread-safety into existing code. They can hide nasty bugs. Use regular mutex (Mutexes) whenever possible.

For further reference:

Recursive mutexes behave like mutexes, but they can be locked multiple times from the same thread before being unlocked. A recursive mutex must be unlocked an equal number of times as it was locked before it is considered to be available again. Where possible on real-time platforms, the mutex provides priority inheritance.

See the mutex (Mutexes) documentation for more information on basic mutex behavior.

etcpal_recursive_mutex are not available on all platforms, and their implementations use different constructs under the hood on various platforms. Also, different platforms affect the behavior of certain functions.

Platform Recursive Mutexes available ETCPAL_RECURSIVE_MUTEX_HAS_TIMED_LOCK Underlying Type
FreeRTOS Yes Yes Recursive Mutexes
Linux Yes No pthread_mutex
macOS Yes No pthread_mutex
MQX No N/A N/A
Windows Yes No Critical Section objects

Macros

#define ETCPAL_RECURSIVE_MUTEX_HAS_TIMED_LOCK   /* platform-defined */
 Whether etcpal_recursive_mutex_timed_lock() is meaningful on this platform. More...
 

Typedefs

typedef PLATFORM_DEFINED etcpal_recursive_mutex_t
 The mutex identifier. More...
 

Functions

bool etcpal_recursive_mutex_create (etcpal_recursive_mutex_t *id)
 Create a new mutex. More...
 
bool etcpal_recursive_mutex_lock (etcpal_recursive_mutex_t *id)
 Lock a mutex. More...
 
bool etcpal_recursive_mutex_try_lock (etcpal_recursive_mutex_t *id)
 Try to lock a mutex. More...
 
bool etcpal_recursive_mutex_timed_lock (etcpal_recursive_mutex_t *id, int timeout_ms)
 Try to lock a mutex, giving up after a timeout. More...
 
void etcpal_recursive_mutex_unlock (etcpal_recursive_mutex_t *id)
 Unlock a mutex. More...
 
void etcpal_recursive_mutex_destroy (etcpal_recursive_mutex_t *id)
 Destroy a mutex object. More...
 

Macro Definition Documentation

◆ ETCPAL_RECURSIVE_MUTEX_HAS_TIMED_LOCK

#define ETCPAL_RECURSIVE_MUTEX_HAS_TIMED_LOCK   /* platform-defined */

Whether etcpal_recursive_mutex_timed_lock() is meaningful on this platform.

If defined to 0, etcpal_recursive_mutex_timed_lock() executes the equivalent of etcpal_recursive_mutex_try_lock() if given a timeout of 0, or etcpal_recursive_mutex_lock() otherwise.

Typedef Documentation

◆ etcpal_recursive_mutex_t

typedef PLATFORM_DEFINED etcpal_recursive_mutex_t

The mutex identifier.

Depending on the platform, this could be a scalar type or a struct.

Function Documentation

◆ etcpal_recursive_mutex_create()

bool etcpal_recursive_mutex_create ( etcpal_recursive_mutex_t id)

Create a new mutex.

Parameters
[out]idMutex identifier on which to create a mutex. If this function returns true, id becomes valid for calls to other etcpal_recursive_mutex API functions.
Returns
true: The mutex was created.
false: The mutex was not created.

◆ etcpal_recursive_mutex_destroy()

void etcpal_recursive_mutex_destroy ( etcpal_recursive_mutex_t id)

Destroy a mutex object.

Parameters
[in]idIdentifier for the mutex to destroy.

◆ etcpal_recursive_mutex_lock()

bool etcpal_recursive_mutex_lock ( etcpal_recursive_mutex_t id)

Lock a mutex.

Blocks until the mutex is locked.

Parameters
[in]idIdentifier for the mutex to lock.
Returns
true: The mutex is locked.
false: The mutex is invalid or an error occurred.

◆ etcpal_recursive_mutex_timed_lock()

bool etcpal_recursive_mutex_timed_lock ( etcpal_recursive_mutex_t id,
int  timeout_ms 
)

Try to lock a mutex, giving up after a timeout.

This function is not honored on all platforms. The value of ETCPAL_RECURSIVE_MUTEX_HAS_TIMED_LOCK can be used to determine whether this function is honored on the current platform. If it is defined to 0, this function executes the equivalent of etcpal_recursive_mutex_try_lock() if timeout_ms is 0, or etcpal_recursive_mutex_lock() otherwise.

Parameters
[in]idIdentifier for the mutex to try to acquire.
[in]timeout_msMaximum amount of time to wait for the mutex to become available, in milliseconds. If ETCPAL_WAIT_FOREVER is given, the result is the same as if etcpal_recursive_mutex_lock() was called.
Returns
true: The mutex is locked.
false: The timeout expired while waiting to lock the mutex, the mutex is invalid or an error occurred.

◆ etcpal_recursive_mutex_try_lock()

bool etcpal_recursive_mutex_try_lock ( etcpal_recursive_mutex_t id)

Try to lock a mutex.

Returns immediately either failure or success.

Parameters
[in]idIdentifier for the mutex to try to lock.
Returns
true: The mutex is locked.
false: The mutex is locked by another thread, the mutex is invalid or an error occurred.

◆ etcpal_recursive_mutex_unlock()

void etcpal_recursive_mutex_unlock ( etcpal_recursive_mutex_t id)

Unlock a mutex.

Parameters
[in]idIdentifier for the mutex to unlock.