diff --git a/.gitlab/ci/check_missing_headers.sh b/.gitlab/ci/check_missing_headers.sh index 25bcc1f35..d4f41c326 100755 --- a/.gitlab/ci/check_missing_headers.sh +++ b/.gitlab/ci/check_missing_headers.sh @@ -5,12 +5,12 @@ LIST="" -for i in $(find spa/include -name '*.h' | sed s#spa/include/##); +for i in $(find spa/include -name '*.h' -a -not -path 'spa/include/spa/utils/cleanup.h' | sed s#spa/include/##); do [ -f "$PREFIX/include/spa-0.2/$i" ] || LIST="$i $LIST" done -for i in $(find src/pipewire -name '*.h' -a -not -name '*private.h' | sed s#src/##); +for i in $(find src/pipewire -name '*.h' -a -not -name '*private.h' -a -not -name 'cleanup.h' | sed s#src/##); do [ -f "$PREFIX/include/pipewire-0.3/$i" ] || LIST="$i $LIST" done diff --git a/spa/include/meson.build b/spa/include/meson.build index 443db7dca..a143402e8 100644 --- a/spa/include/meson.build +++ b/spa/include/meson.build @@ -14,5 +14,8 @@ spa_sections = [ spa_headers = 'spa' # used by doxygen install_subdir('spa', - install_dir : get_option('includedir') / spa_name + install_dir : get_option('includedir') / spa_name, + exclude_files : [ + 'utils/cleanup.h', + ], ) diff --git a/spa/include/spa/utils/cleanup.h b/spa/include/spa/utils/cleanup.h new file mode 100644 index 000000000..04e2bd193 --- /dev/null +++ b/spa/include/spa/utils/cleanup.h @@ -0,0 +1,98 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2023 PipeWire authors */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_UTILS_CLEANUP_H +#define SPA_UTILS_CLEANUP_H + +#if !defined(__has_attribute) || !__has_attribute(__cleanup__) +#error "attribute `cleanup` is required" +#endif + +#define spa_cleanup(func) __attribute__((__cleanup__(func))) + +#define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \ +typedef __typeof__(type) _spa_auto_cleanup_type_ ## name; \ +static inline void _spa_auto_cleanup_func_ ## name (__typeof__(type) *thing) \ +{ \ + __VA_ARGS__ \ +} + +#define spa_auto(name) \ + spa_cleanup(_spa_auto_cleanup_func_ ## name) \ + _spa_auto_cleanup_type_ ## name + +#define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...) \ +typedef __typeof__(type) * _spa_autoptr_cleanup_type_ ## name; \ +static inline void _spa_autoptr_cleanup_func_ ## name (__typeof__(type) **thing) \ +{ \ + __VA_ARGS__ \ +} + +#define spa_autoptr(name) \ + spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \ + _spa_autoptr_cleanup_type_ ## name + +#define spa_exchange(var, new_value) \ +__extension__ ({ \ + __typeof__(var) _old_value = (var); \ + (var) = (new_value); \ + _old_value; \ +}) + +#define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL)) +#define spa_steal_fd(fd) spa_exchange((fd), -1) + +/* ========================================================================== */ + +#include + +#define spa_clear_ptr(ptr, destructor) \ +__extension__ ({ \ + __typeof__(*(ptr)) *_old_value = spa_steal_ptr(ptr); \ + if (_old_value) \ + destructor(_old_value); \ + (void) 0; \ +}) + +static inline void _spa_autofree_cleanup_func(void *p) +{ + free(*(void **) p); +} +#define spa_autofree spa_cleanup(_spa_autofree_cleanup_func) + +/* ========================================================================== */ + +#include + +#define spa_clear_fd(fd) \ +__extension__ ({ \ + int _old_value = spa_steal_fd(fd), _res = 0; \ + if (_old_value >= 0) \ + _res = close(_old_value); \ + _res; \ +}) + +static inline void _spa_autoclose_cleanup_func(int *fd) +{ + spa_clear_fd(*fd); +} +#define spa_autoclose spa_cleanup(_spa_autoclose_cleanup_func) + +/* ========================================================================== */ + +#include + +SPA_DEFINE_AUTOPTR_CLEANUP(FILE, FILE, { + spa_clear_ptr(*thing, fclose); +}) + +/* ========================================================================== */ + +#include + +SPA_DEFINE_AUTOPTR_CLEANUP(DIR, DIR, { + spa_clear_ptr(*thing, closedir); +}) + +#endif /* SPA_UTILS_CLEANUP_H */ diff --git a/src/pipewire/cleanup.h b/src/pipewire/cleanup.h new file mode 100644 index 000000000..6a54e363b --- /dev/null +++ b/src/pipewire/cleanup.h @@ -0,0 +1,21 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2023 PipeWire authors */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_CLEANUP_H +#define PIPEWIRE_CLEANUP_H + +#include + +#include +#include + +SPA_DEFINE_AUTOPTR_CLEANUP(pw_properties, struct pw_properties, { + spa_clear_ptr(*thing, pw_properties_free); +}) + +SPA_DEFINE_AUTO_CLEANUP(pw_strv, char **, { + spa_clear_ptr(*thing, pw_free_strv); +}) + +#endif /* PIPEWIRE_CLEANUP_H */