6#ifndef ZEPHYR_INCLUDE_CLEANUP_H_
7#define ZEPHYR_INCLUDE_CLEANUP_H_
22#if defined(CONFIG_SCOPE_CLEANUP_HELPERS) || defined(__DOXYGEN__)
85#define SCOPE_VAR_DEFINE(_name, _type, _exit_fn, _init_fn, ...) \
86 static inline void __maybe_unused cleanup_##_name##_exit(_type *p) \
91 static inline _type __maybe_unused cleanup_##_name##_init(__VA_ARGS__) \
96 typedef _type cleanup_##_name##_t
118#define SCOPE_GUARD_DEFINE(_name, _type, _lock, _unlock) \
120 guard_##_name, _type, if (_T != NULL) { _unlock; }, ({ \
128#define Z_SCOPE_DEFER_DEFINE_VOID(_func) \
129 SCOPE_VAR_DEFINE(defer_##_func, void *, (void)_T; (void)_func(), NULL, void)
131#define Z_DEFER_CTX_ARG(idx, t) t arg##idx;
132#define Z_DEFER_FUNC_ARG(idx, t) t arg##idx
133#define Z_DEFER_INIT_ARG(idx, _) .arg##idx = arg##idx
134#define Z_DEFER_EXIT_ARG(idx, _) _T.arg##idx
137#define Z_SCOPE_DEFER_DEFINE_N(_func, ...) \
138 struct defer_##_func##_ctx { \
139 FOR_EACH_IDX(Z_DEFER_CTX_ARG, (), __VA_ARGS__) \
141 SCOPE_VAR_DEFINE(defer_##_func, struct defer_##_func##_ctx, \
142 (void)_func(FOR_EACH_IDX(Z_DEFER_EXIT_ARG, (Z_COMMA), __VA_ARGS__)), \
143 {FOR_EACH_IDX(Z_DEFER_INIT_ARG, (Z_COMMA), __VA_ARGS__)}, \
144 FOR_EACH_IDX(Z_DEFER_FUNC_ARG, (Z_COMMA), __VA_ARGS__))
164#define SCOPE_DEFER_DEFINE(_func, ...) \
165 COND_CODE_0(NUM_VA_ARGS(__VA_ARGS__), \
166 (Z_SCOPE_DEFER_DEFINE_VOID(_func)), \
167 (Z_SCOPE_DEFER_DEFINE_N(_func, __VA_ARGS__)))
176#define Z_UNIQUE_ID(_prefix) _CONCAT(_CONCAT(Z_UNIQUE_ID_, _prefix), __COUNTER__)
199#define scope_var(_name, _var) \
200 cleanup_##_name##_t _var __cleanup(cleanup_##_name##_exit) = cleanup_##_name##_init
224#define scope_var_init(_name, _var, _init_expr) \
225 cleanup_##_name##_t _var __cleanup(cleanup_##_name##_exit) = (_init_expr)
240#define scope_guard(_name) scope_var(guard_##_name, Z_UNIQUE_ID(guard))
255#define scope_defer(_name) scope_var(defer_##_name, Z_UNIQUE_ID(defer))