Zephyr API Documentation 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
Cleanup Helper Interface

Macros

#define SCOPE_VAR_DEFINE(_name, _type, _exit_fn, _init_fn, ...)
 Define a scoped variable type.
#define SCOPE_GUARD_DEFINE(_name, _type, _lock, _unlock)
 Define a scoped guard type.
#define SCOPE_COND_GUARD_DEFINE(_name, _type, _try_lock, _unlock)
 Define a conditional (failable) scoped guard type.
#define SCOPE_DEFER_DEFINE(_func, ...)
 Define a scoped defer type.
#define scope_var(_name, _var)
 Declare a variable with automatic cleanup.
#define scope_var_init(_name, _var, _init_expr)
 Declare a variable with automatic cleanup using direct initialization.
#define scope_guard(_name)
 Acquire a scoped guard lock.
#define scoped_guard(_name, ...)
 Acquire a guard for the lifetime of the following block.
#define scoped_cond_guard(_name, _fail, ...)
 Conditionally acquire a guard for the lifetime of the following block.
#define scope_defer(_name)
 Register a scoped deferred call.

Detailed Description

Macro Definition Documentation

◆ SCOPE_COND_GUARD_DEFINE

#define SCOPE_COND_GUARD_DEFINE ( _name,
_type,
_try_lock,
_unlock )

#include <zephyr/cleanup.h>

Value:
SCOPE_VAR_DEFINE(guard_##_name, _type, if (_T != NULL) { _unlock; }, \
((_try_lock) ? _T : NULL), _type _T)
#define SCOPE_VAR_DEFINE(_name, _type, _exit_fn, _init_fn,...)
Define a scoped variable type.
Definition cleanup.h:85

Define a conditional (failable) scoped guard type.

This macro defines a guard whose lock acquisition may fail, for use with scoped_cond_guard. Unlike SCOPE_GUARD_DEFINE, the acquire expression is evaluated for success: when it evaluates truthy the guard stores _type _T and the release expression runs on scope exit; when it evaluates falsy the guard stores NULL and nothing is released.

Parameters
_nameName of the guard (will be prefixed with guard_)
_typeType of the lock object (must be a pointer type)
_try_lockExpression evaluating truthy when the lock is acquired (can reference _T)
_unlockExpression to release the lock (can reference _T)
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

SCOPE_COND_GUARD_DEFINE(k_mutex_try, struct k_mutex *,
(void)k_mutex_unlock(_T));
#define SCOPE_COND_GUARD_DEFINE(_name, _type, _try_lock, _unlock)
Define a conditional (failable) scoped guard type.
Definition cleanup.h:150
#define K_NO_WAIT
Generate null timeout delay.
Definition kernel.h:1572
int k_mutex_unlock(struct k_mutex *mutex)
Unlock a mutex.
int k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout)
Lock a mutex.
Kernel mutex structure.
Definition kernel.h:3477

◆ scope_defer

#define scope_defer ( _name)

#include <zephyr/cleanup.h>

Value:
scope_var(defer_##_name, Z_UNIQUE_ID(defer))
#define scope_var(_name, _var)
Declare a variable with automatic cleanup.
Definition cleanup.h:251

Register a scoped deferred call.

This macro creates a defer variable with an automatically generated unique name. The defer will execute its cleanup action when going out of scope.

Parameters
_nameName of the defer type (defined by SCOPE_DEFER_DEFINE or SCOPE_VAR_DEFINE with defer_ prefix)
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

#define scope_defer(_name)
Register a scoped deferred call.
Definition cleanup.h:371

◆ SCOPE_DEFER_DEFINE

#define SCOPE_DEFER_DEFINE ( _func,
... )

#include <zephyr/cleanup.h>

Value:
COND_CODE_0(NUM_VA_ARGS(__VA_ARGS__), \
(Z_SCOPE_DEFER_DEFINE_VOID(_func)), \
(Z_SCOPE_DEFER_DEFINE_N(_func, __VA_ARGS__)))
#define NUM_VA_ARGS(...)
Number of arguments in the variable arguments list.
Definition util_macro.h:725
#define COND_CODE_0(_flag, _if_0_code, _else_code)
Like COND_CODE_1() except tests if _flag is 0.
Definition util_macro.h:225

Define a scoped defer type.

This macro defines a defer that executes a cleanup function when the variable goes out of scope. Unlike guards, defers don't acquire a resource on initialization.

Parameters
_funcThe function to call at cleanup
...The argument types to pass to the cleanup function
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

#define SCOPE_DEFER_DEFINE(_func,...)
Define a scoped defer type.
Definition cleanup.h:192
void k_free(void *ptr)
Free memory allocated from heap.

◆ scope_guard

#define scope_guard ( _name)

#include <zephyr/cleanup.h>

Value:
scope_var(guard_##_name, Z_UNIQUE_ID(guard))

Acquire a scoped guard lock.

This macro creates a guard variable with an automatically generated unique name. The guard will acquire the lock on initialization and release it when going out of scope.

Parameters
_nameName of the guard type (defined by SCOPE_GUARD_DEFINE or SCOPE_VAR_DEFINE with guard_ prefix)
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

scope_guard(k_mutex)(&my_mutex);
#define scope_guard(_name)
Acquire a scoped guard lock.
Definition cleanup.h:292

◆ SCOPE_GUARD_DEFINE

#define SCOPE_GUARD_DEFINE ( _name,
_type,
_lock,
_unlock )

#include <zephyr/cleanup.h>

Value:
guard_##_name, _type, if (_T != NULL) { _unlock; }, ({ \
_lock; \
_T; \
}), \
_type _T)

Define a scoped guard type.

This macro defines a guard that automatically acquires a lock on initialization and releases it when going out of scope.

Parameters
_nameName of the guard (will be prefixed with guard_)
_typeType of the lock object (typically a pointer)
_lockExpression to acquire the lock (can reference _T)
_unlockExpression to release the lock (can reference _T)
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

(void)k_mutex_lock(_T, K_FOREVER),
(void)k_mutex_unlock(_T));
#define SCOPE_GUARD_DEFINE(_name, _type, _lock, _unlock)
Define a scoped guard type.
Definition cleanup.h:118
#define K_FOREVER
Generate infinite timeout delay.
Definition kernel.h:1682

◆ scope_var

#define scope_var ( _name,
_var )

#include <zephyr/cleanup.h>

Value:
cleanup_##_name##_t _var __cleanup(cleanup_##_name##_exit) = cleanup_##_name##_init

Declare a variable with automatic cleanup.

This macro declares a variable with automatic cleanup using a previously defined cleanup helper. The variable will be automatically cleaned up when it goes out of scope.

The variable is initialized by calling the init function defined in SCOPE_VAR_DEFINE. Use scope_var_init if you want to initialize the variable with a direct expression instead of calling the init function.

Parameters
_nameName of the cleanup helper (defined by SCOPE_VAR_DEFINE)
_varName of the variable to declare
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

scope_var(some_type, my_var)(init_args);
See also
scope_var_init for direct initialization without calling the init function

◆ SCOPE_VAR_DEFINE

#define SCOPE_VAR_DEFINE ( _name,
_type,
_exit_fn,
_init_fn,
... )

#include <zephyr/cleanup.h>

Value:
static inline void __maybe_unused cleanup_##_name##_exit(_type *p) \
{ \
_type _T = *p; \
_exit_fn; \
} \
static inline _type __maybe_unused cleanup_##_name##_init(__VA_ARGS__) \
{ \
_type t = _init_fn; \
return t; \
} \
typedef _type cleanup_##_name##_t

Define a scoped variable type.

This macro defines a new cleanup helper that can be used with the __cleanup attribute to automatically execute cleanup code when a variable goes out of scope.

Parameters
_nameName of the cleanup helper
_typeType of the variable to be cleaned up
_exit_fnCleanup code to execute when variable goes out of scope (can reference _T)
_init_fnInitialization expression for the variable
...Initialization arguments (variadic)

The macro creates:

  • An exit function cleanup_<name>_exit that executes cleanup code
  • An init function cleanup_<name>_init that initializes the variable
  • A typedef cleanup_<name>_t for the type
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

struct foo {
int value;
};
static inline struct foo *foo_constructor(int value)
{
struct foo *ptr = k_malloc(sizeof(struct foo));
if (ptr != NULL) {
ptr->value = value;
}
return ptr;
}
static inline void foo_destructor(struct foo *ptr)
{
k_free(ptr);
}
// Define the cleanup helper
SCOPE_VAR_DEFINE(foo, struct foo *, foo_destructor(_T), foo_constructor(val), int val);
static int some_function(void)
{
// The scope_var macro declares 'f' with automatic cleanup
scope_var(foo, f)(42);
if (f == NULL) {
return -ENOMEM;
}
// Use f normally - it points to an allocated and initialized struct foo
printk("Value: %d\n", f->value);
// No need to manually free - foo_destructor is called automatically
// when 'f' goes out of scope
}
void * k_malloc(size_t size)
Allocate memory from the heap.
#define ENOMEM
Not enough core.
Definition errno.h:50
static void printk(const char *fmt,...)
Print kernel debugging message.
Definition printk.h:64

◆ scope_var_init

#define scope_var_init ( _name,
_var,
_init_expr )

#include <zephyr/cleanup.h>

Value:
cleanup_##_name##_t _var __cleanup(cleanup_##_name##_exit) = (_init_expr)

Declare a variable with automatic cleanup using direct initialization.

This macro declares a variable with automatic cleanup using a previously defined cleanup helper. The variable will be automatically cleaned up when it goes out of scope.

Unlike scope_var, this macro accepts a direct initialization expression instead of calling the init function defined in SCOPE_VAR_DEFINE. Use this when you need to bypass the init function and initialize the variable directly (e.g., with a struct initializer, a different function, or a literal value).

Parameters
_nameName of the cleanup helper (defined by SCOPE_VAR_DEFINE)
_varName of the variable to declare
_init_exprDirect initialization expression for the variable (e.g., {0}, NULL, or a function call)
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

scope_var_init(some_type, my_var, {0});
#define scope_var_init(_name, _var, _init_expr)
Declare a variable with automatic cleanup using direct initialization.
Definition cleanup.h:276
See also
scope_var for initialization using the init function

◆ scoped_cond_guard

#define scoped_cond_guard ( _name,
_fail,
... )

#include <zephyr/cleanup.h>

Value:
Z_SCOPED_COND_GUARD(_name, Z_UNIQUE_ID(scoped_g), Z_UNIQUE_ID(scoped_done), _fail, \
__VA_ARGS__)

Conditionally acquire a guard for the lifetime of the following block.

This macro attempts to acquire a conditional (failable) scoped guard and, on success, holds it for the duration of the brace block that immediately follows, releasing it as soon as the block is exited. If the lock cannot be acquired, _fail is executed and the block is skipped.

On success the block runs exactly once and the lock is released on any exit from the block, including break, return and goto (continue behaves like break).

Parameters
_nameName of the guard type (defined by SCOPE_COND_GUARD_DEFINE)
_failStatement executed when the lock cannot be acquired (e.g. break, return -EBUSY, or {} to silently skip the block)
...Arguments to acquire the guard (e.g. the lock object)
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

scoped_cond_guard(k_mutex_try, return -EBUSY, &my_mutex) {
// lock held only inside these braces, runs only if acquired
}
#define scoped_cond_guard(_name, _fail,...)
Conditionally acquire a guard for the lifetime of the following block.
Definition cleanup.h:354
#define EBUSY
Mount device busy.
Definition errno.h:54

◆ scoped_guard

#define scoped_guard ( _name,
... )

#include <zephyr/cleanup.h>

Value:
Z_SCOPED_GUARD(_name, Z_UNIQUE_ID(scoped_g), Z_UNIQUE_ID(scoped_done), __VA_ARGS__)

Acquire a guard for the lifetime of the following block.

This macro acquires a scoped guard lock and holds it for the duration of the brace block that immediately follows, releasing it as soon as the block is exited. Unlike scope_guard, whose guard lives until the end of the enclosing scope, the guard created here is bound to its own block.

The block runs exactly once. The lock is released on any exit from the block, including break, return and goto. Note that, because the block is implemented with a hidden loop, break and continue leave the guarded block rather than affecting an enclosing loop.

This macro also accepts a guard defined with SCOPE_COND_GUARD_DEFINE. In that case the block is skipped (and nothing is held) if the lock cannot be acquired; use scoped_cond_guard when you need to run a statement on acquisition failure.

Parameters
_nameName of the guard type (defined by SCOPE_GUARD_DEFINE or SCOPE_COND_GUARD_DEFINE)
...Arguments to acquire the guard (e.g. the lock object)
Attention
Available only when the following Kconfig option is enabled: CONFIG_SCOPE_CLEANUP_HELPERS.

Usage:

scoped_guard(k_mutex, &my_mutex) {
// lock held only inside these braces
}
// lock released here
#define scoped_guard(_name,...)
Acquire a guard for the lifetime of the following block.
Definition cleanup.h:325