5 #ifndef SPA_UTILS_CLEANUP_H
6 #define SPA_UTILS_CLEANUP_H
8 #define spa_exchange(var, new_value) \
10 __typeof__(var) *_ptr_ = &(var); \
11 __typeof__(var) _old_value_ = *_ptr_; \
12 *_ptr_ = (new_value); \
18 #if __GNUC__ >= 10 || defined(__clang__)
19 #define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL))
21 #define spa_steal_ptr(ptr) spa_exchange((ptr), NULL)
24 #define spa_clear_ptr(ptr, destructor) \
26 __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \
28 destructor(_old_value); \
37 #define spa_steal_fd(fd) spa_exchange((fd), -1)
39 #define spa_clear_fd(fd) \
41 int _old_value = spa_steal_fd(fd), _res = 0; \
42 if (_old_value >= 0) \
43 _res = close(_old_value); \
49 #ifdef __has_attribute
50 #if __has_attribute(__cleanup__)
51 #define spa_cleanup(func) __attribute__((__cleanup__(func)))
57 #define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \
58 typedef __typeof__(type) _spa_auto_cleanup_type_ ## name; \
59 static inline void _spa_auto_cleanup_func_ ## name (__typeof__(type) *thing) \
61 int _save_errno = errno; \
63 errno = _save_errno; \
66 #define spa_auto(name) \
67 spa_cleanup(_spa_auto_cleanup_func_ ## name) \
68 _spa_auto_cleanup_type_ ## name
70 #define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...) \
71 typedef __typeof__(type) * _spa_autoptr_cleanup_type_ ## name; \
72 static inline void _spa_autoptr_cleanup_func_ ## name (__typeof__(type) **thing) \
74 int _save_errno = errno; \
76 errno = _save_errno; \
79 #define spa_autoptr(name) \
80 spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \
81 _spa_autoptr_cleanup_type_ ## name
87 static inline void _spa_autofree_cleanup_func(
void *p)
89 int save_errno = errno;
93 #define spa_autofree spa_cleanup(_spa_autofree_cleanup_func)
97 static inline void _spa_autoclose_cleanup_func(
int *fd)
99 int save_errno = errno;
103 #define spa_autoclose spa_cleanup(_spa_autoclose_cleanup_func)
109 SPA_DEFINE_AUTOPTR_CLEANUP(FILE, FILE, {
110 spa_clear_ptr(*thing, fclose);
117 SPA_DEFINE_AUTOPTR_CLEANUP(DIR, DIR, {
118 spa_clear_ptr(*thing, closedir);
123 #define SPA_DEFINE_AUTO_CLEANUP(name, type, ...)
124 #define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...)