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#if defined(__has_attribute) && __has_attribute(__cleanup__) 
   51#define spa_cleanup(func) __attribute__((__cleanup__(func))) 
   53#define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \ 
   54typedef __typeof__(type) _spa_auto_cleanup_type_ ## name; \ 
   55static inline void _spa_auto_cleanup_func_ ## name (__typeof__(type) *thing) \ 
   57        int _save_errno = errno; \ 
   59        errno = _save_errno; \ 
   62#define spa_auto(name) \ 
   63        spa_cleanup(_spa_auto_cleanup_func_ ## name) \ 
   64        _spa_auto_cleanup_type_ ## name 
   66#define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...) \ 
   67typedef __typeof__(type) * _spa_autoptr_cleanup_type_ ## name; \ 
   68static inline void _spa_autoptr_cleanup_func_ ## name (__typeof__(type) **thing) \ 
   70        int _save_errno = errno; \ 
   72        errno = _save_errno; \ 
   75#define spa_autoptr(name) \ 
   76        spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \ 
   77        _spa_autoptr_cleanup_type_ ## name 
   83static inline void _spa_autofree_cleanup_func(
void *p)
 
   85        int save_errno = errno;
 
   89#define spa_autofree spa_cleanup(_spa_autofree_cleanup_func) 
   93static inline void _spa_autoclose_cleanup_func(
int *fd)
 
   95        int save_errno = errno;
 
   99#define spa_autoclose spa_cleanup(_spa_autoclose_cleanup_func) 
  105SPA_DEFINE_AUTOPTR_CLEANUP(FILE, FILE, {
 
  106        spa_clear_ptr(*thing, fclose);
 
  113SPA_DEFINE_AUTOPTR_CLEANUP(DIR, DIR, {
 
  114        spa_clear_ptr(*thing, closedir);
 
  119#define SPA_DEFINE_AUTO_CLEANUP(name, type, ...)
 
  120#define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...)