pub unsafe extern "C" fn mutex_cancel(mc: *mut mutex_cancel_t)
Expand description
@brief Cancels a call to @ref mutex_lock_cancelable
@param[in,out] mc Mutex cancellation structure referring to the thread calling @ref mutex_lock_cancelable and to the mutex to cancel the operation on
@note This function is considered internal. Out of tree users should be aware that breaking API changes or removal of this API without an deprecation period might happen.
@pre @p mc is used to cancel at most one call to @ref mutex_lock_cancelable. (You can reinitialize the same memory to safely reuse it.) @warning You MUST NOT call this function once the thread referred to by @p mc reuses the mutex object referred to by @p mc (not counting the call to @ref mutex_lock_cancelable @p mc was used in). @note It is safe to call this function from IRQ context, e.g. from a timer interrupt. @note It is safe to call this function more than once on the same @p mc while it is still valid (see the warning above). The first call will cancel the operation and subsequent calls will have no effect.
@details If @p thread is currently running (or pending), a subsequent call from @p thread to @ref mutex_lock_cancelable will also fail
Canonical use:
static void timeout_cb(void *arg) {
mutex_cancel(arg);
}
int ztimer_mutex_lock_timeout(ztimer_clock_t *clock, mutex_t *mutex,
uint32_t timeout)
{
mutex_cancel_t mc = mutex_cancel_init(mutex);
ztimer_t t = { .callback = timeout_cb, .arg = &mc };
ztimer_set(clock, &t, timeout);
if (mutex_lock_cancelable(&mc)) {
return -ECANCELED;
}
ztimer_remove(clock, &t);
return 0;
}
In the above example a simple implementation of how to implement mutex locking with a timeout is given. There are two corner cases:
- The call to @ref mutex_cancel could occur before the call to
@ref mutex_lock_cancelable. (E.g. for
timeout == 0
.) - The call to @ref mutex_cancel could occur right after the mutex was
successfully obtained, but before
ztimer_remove()
was executed.
In the first corner case the cancellation is stored in @p mc. Hence, the subsequent call to @ref mutex_lock_cancelable gets indeed canceled. In the second corner case the cancellation is also stored in @p mc but never used - the mutex cancellation structure @p mc is not allowed to be reused without reinitialization.