mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-11-05 16:26:16 +00:00
65d949558b
systemd, dbus-broker, and many glib applications heavily utilize the GNU C attribute "cleanup" to achieve C++ RAII-like semantics for local resource management. This commit introduces essentialy same mechanism into pipewire. At the moment, this is inteded to be a strictly private API. free() and close() as cleanup targets are sufficiently common to warrant their own special macros: spa_autofree char *s = strdup(p); // will call `free(s)` at the end of the lifetime of `s` spa_autoclose int fd = openat(...); // will call `close(fd)` if `fd >= 0` at the end of the lifetime of `fd` However, with `spa_auto()` or `spa_autoptr()` it is possible to define other variables that will be cleaned up properly. Currently four are supported: spa_autoptr(FILE) f = fopen(...); // `f` has type `FILE *` // will call `fclose(f)` if `f != NULL` spa_autoptr(DIR) d = opendir(...); // `d` has type `DIR *` // will call `closedir(d)` if `d != NULL` spa_autoptr(pw_properties) p = pw_properties_new(NULL, NULL); // `p` has type `struct pw_properties *` // will call `pw_properties_free(p)` spa_auto(pw_strv) v = pw_split_strv(...); // `v` has type `char **` // will call `pw_strv_free(v)` It is possible to add support for other types, e.g. SPA_DEFINE_AUTOPTR_CLEANUP(pw_main_loop, struct pw_main_loop, { // the pointer can be accessed using `*thing` // `thing` has type `struct pw_main_loop **` spa_clear_ptr(*thing, pw_main_loop_destroy); }) spa_autoptr(pw_main_loop) l = ...; // `l` has type `struct pw_main_loop *` // will call `pw_main_loop_destroy(l)` or SPA_DEFINE_AUTO_CLEANUP(spa_pod_dynamic_builder, struct spa_pod_dynamic_builder, { // `thing` has type `struct spa_pod_dynamic_builder *` spa_pod_dynamic_builder_clean(thing); }) spa_auto(spa_pod_dynamic_builder) builder = ... // `builder` has type `struct spa_pod_dynamic_builder` // will call `spa_pod_dynamic_builder_clean(&builder)` The first argument is always an arbitrary name. This name must be passed to `spa_auto()` and `spa_autoptr()` as it is what determines the actual type and destructor used. The second parameter is the concrete type. For `SPA_DEFINE_AUTO_CLEANUP()` this is the concrete type to be used, while for `SPA_DEFINE_AUTOPTR_CLEANUP()` it is the concrete type without the outermost pointer. That is, SPA_DEFINE_AUTOPTR_CLEANUP(A, foo, ...) SPA_DEFINE_AUTO_CLEANUP(B, foo, ...) spa_autoptr(A) x; // `x` has type `foo *` spa_auto(B) y; // `y` has type `foo` A couple other macros are also added: spa_clear_ptr(ptr, destructor) // calls `destructor(ptr)` if `ptr != NULL` and sets `ptr` to `NULL` spa_clear_fd(fd) // calls `close(fd)` if `fd >= 0` and sets `fd` to -1 spa_steal_ptr(ptr) // sets `ptr` to `NULL` and returns the old value, // useful for preventing the auto cleanup mechanism from kicking in // when returning the pointer from a function spa_steal_fd(fd) // sets `fd` to -1 and returns the old value |
||
---|---|---|
.. | ||
ci | ||
issue_templates |