5 #ifndef SPA_UTILS_CLEANUP_H 6 #define SPA_UTILS_CLEANUP_H 8 #if !defined(__has_attribute) || !__has_attribute(__cleanup__) 9 #error "attribute `cleanup` is required" 12 #define spa_cleanup(func) __attribute__((__cleanup__(func))) 14 #define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \ 15 typedef __typeof__(type) _spa_auto_cleanup_type_ ## name; \ 16 static inline void _spa_auto_cleanup_func_ ## name (__typeof__(type) *thing) \ 21 #define spa_auto(name) \ 22 spa_cleanup(_spa_auto_cleanup_func_ ## name) \ 23 _spa_auto_cleanup_type_ ## name 25 #define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...) \ 26 typedef __typeof__(type) * _spa_autoptr_cleanup_type_ ## name; \ 27 static inline void _spa_autoptr_cleanup_func_ ## name (__typeof__(type) **thing) \ 32 #define spa_autoptr(name) \ 33 spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \ 34 _spa_autoptr_cleanup_type_ ## name 36 #define spa_exchange(var, new_value) \ 38 __typeof__(var) _old_value = (var); \ 39 (var) = (new_value); \ 43 #if __GNUC__ > 10 || defined(__clang__) 44 #define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL)) 46 #define spa_steal_ptr(ptr) ((__typeof__(ptr)) spa_exchange((ptr), NULL)) 49 #define spa_steal_fd(fd) spa_exchange((fd), -1) 56 #if __GNUC__ > 10 || defined(__clang__) 57 #define spa_clear_ptr(ptr, destructor) \ 59 __typeof__(*(ptr)) *_old_value = spa_steal_ptr(ptr); \ 61 destructor(_old_value); \ 65 #define spa_clear_ptr(ptr, destructor) \ 67 __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \ 69 destructor(_old_value); \ 74 static inline void _spa_autofree_cleanup_func(
void *p)
78 #define spa_autofree spa_cleanup(_spa_autofree_cleanup_func) 84 #define spa_clear_fd(fd) \ 86 int _old_value = spa_steal_fd(fd), _res = 0; \ 87 if (_old_value >= 0) \ 88 _res = close(_old_value); \ 92 static inline void _spa_autoclose_cleanup_func(
int *fd)
96 #define spa_autoclose spa_cleanup(_spa_autoclose_cleanup_func) 102 SPA_DEFINE_AUTOPTR_CLEANUP(FILE, FILE, {
103 spa_clear_ptr(*thing, fclose);
110 SPA_DEFINE_AUTOPTR_CLEANUP(DIR, DIR, {
111 spa_clear_ptr(*thing, closedir);