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; }, ({ \
150#define SCOPE_COND_GUARD_DEFINE(_name, _type, _try_lock, _unlock) \
151 SCOPE_VAR_DEFINE(guard_##_name, _type, if (_T != NULL) { _unlock; }, \
152 ((_try_lock) ? _T : NULL), _type _T)
156#define Z_SCOPE_DEFER_DEFINE_VOID(_func) \
157 SCOPE_VAR_DEFINE(defer_##_func, void *, (void)_T; (void)_func(), NULL, void)
159#define Z_DEFER_CTX_ARG(idx, t) t arg##idx;
160#define Z_DEFER_FUNC_ARG(idx, t) t arg##idx
161#define Z_DEFER_INIT_ARG(idx, _) .arg##idx = arg##idx
162#define Z_DEFER_EXIT_ARG(idx, _) _T.arg##idx
165#define Z_SCOPE_DEFER_DEFINE_N(_func, ...) \
166 struct defer_##_func##_ctx { \
167 FOR_EACH_IDX(Z_DEFER_CTX_ARG, (), __VA_ARGS__) \
169 SCOPE_VAR_DEFINE(defer_##_func, struct defer_##_func##_ctx, \
170 (void)_func(FOR_EACH_IDX(Z_DEFER_EXIT_ARG, (Z_COMMA), __VA_ARGS__)), \
171 {FOR_EACH_IDX(Z_DEFER_INIT_ARG, (Z_COMMA), __VA_ARGS__)}, \
172 FOR_EACH_IDX(Z_DEFER_FUNC_ARG, (Z_COMMA), __VA_ARGS__))
192#define SCOPE_DEFER_DEFINE(_func, ...) \
193 COND_CODE_0(NUM_VA_ARGS(__VA_ARGS__), \
194 (Z_SCOPE_DEFER_DEFINE_VOID(_func)), \
195 (Z_SCOPE_DEFER_DEFINE_N(_func, __VA_ARGS__)))
204#define Z_UNIQUE_ID(_prefix) _CONCAT(_CONCAT(Z_UNIQUE_ID_, _prefix), __COUNTER__)
213#define Z_SCOPED_GUARD(_name, _g, _done, ...) \
214 for (int _done = 0; _done == 0; _done = 1) \
215 for (scope_var(guard_##_name, _g)(__VA_ARGS__); _done == 0 && _g != NULL; \
223#define Z_SCOPED_COND_GUARD(_name, _g, _done, _fail, ...) \
224 for (int _done = 0; _done == 0; _done = 1) \
225 for (scope_var(guard_##_name, _g)(__VA_ARGS__); _done == 0; _done = 1) \
251#define scope_var(_name, _var) \
252 cleanup_##_name##_t _var __cleanup(cleanup_##_name##_exit) = cleanup_##_name##_init
276#define scope_var_init(_name, _var, _init_expr) \
277 cleanup_##_name##_t _var __cleanup(cleanup_##_name##_exit) = (_init_expr)
292#define scope_guard(_name) scope_var(guard_##_name, Z_UNIQUE_ID(guard))
325#define scoped_guard(_name, ...) \
326 Z_SCOPED_GUARD(_name, Z_UNIQUE_ID(scoped_g), Z_UNIQUE_ID(scoped_done), __VA_ARGS__)
354#define scoped_cond_guard(_name, _fail, ...) \
355 Z_SCOPED_COND_GUARD(_name, Z_UNIQUE_ID(scoped_g), Z_UNIQUE_ID(scoped_done), _fail, \
371#define scope_defer(_name) scope_var(defer_##_name, Z_UNIQUE_ID(defer))