PipeWire
1.6.4
Toggle main menu visibility
Loading...
Searching...
No Matches
cleanup.h
1
/* Simple Plugin API */
2
/* SPDX-FileCopyrightText: Copyright © 2023 PipeWire authors */
3
/* SPDX-License-Identifier: MIT */
4
5
#ifndef SPA_UTILS_CLEANUP_H
6
#define SPA_UTILS_CLEANUP_H
7
8
#define spa_exchange(var, new_value) \
9
__extension__ ({ \
10
__typeof__(var) *_ptr_ = &(var); \
11
__typeof__(var) _old_value_ = *_ptr_; \
12
*_ptr_ = (new_value); \
13
_old_value_; \
14
})
15
16
/* ========================================================================== */
17
18
#if __GNUC__ >= 10 || defined(__clang__)
19
#define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL))
20
#else
21
#define spa_steal_ptr(ptr) spa_exchange((ptr), NULL)
22
#endif
23
24
#define spa_clear_ptr(ptr, destructor) \
25
__extension__ ({ \
26
__typeof__(ptr) _old_value = spa_steal_ptr(ptr); \
27
if (_old_value) \
28
destructor(_old_value); \
29
(void) 0; \
30
})
31
32
/* ========================================================================== */
33
34
#include <errno.h>
35
#include <unistd.h>
36
37
#define spa_steal_fd(fd) spa_exchange((fd), -1)
38
39
#define spa_clear_fd(fd) \
40
__extension__ ({ \
41
int _old_value = spa_steal_fd(fd), _res = 0; \
42
if (_old_value >= 0) \
43
_res = close(_old_value); \
44
_res; \
45
})
46
47
/* ========================================================================== */
48
49
#ifdef __has_attribute
50
#if __has_attribute(__cleanup__)
51
#define spa_cleanup(func) __attribute__((__cleanup__(func)))
52
#endif
53
#endif
54
55
#ifdef spa_cleanup
56
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) \
60
{ \
61
int _save_errno = errno; \
62
__VA_ARGS__ \
63
errno = _save_errno; \
64
}
65
66
#define spa_auto(name) \
67
spa_cleanup(_spa_auto_cleanup_func_ ## name) \
68
_spa_auto_cleanup_type_ ## name
69
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) \
73
{ \
74
int _save_errno = errno; \
75
__VA_ARGS__ \
76
errno = _save_errno; \
77
}
78
79
#define spa_autoptr(name) \
80
spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \
81
_spa_autoptr_cleanup_type_ ## name
82
83
/* ========================================================================== */
84
85
#include <stdlib.h>
86
87
static
inline
void
_spa_autofree_cleanup_func(
void
*p)
88
{
89
int
save_errno = errno;
90
free(*(
void
**) p);
91
errno = save_errno;
92
}
93
#define spa_autofree spa_cleanup(_spa_autofree_cleanup_func)
94
95
/* ========================================================================== */
96
97
static
inline
void
_spa_autoclose_cleanup_func(
int
*fd)
98
{
99
int
save_errno = errno;
100
spa_clear_fd(*fd);
101
errno = save_errno;
102
}
103
#define spa_autoclose spa_cleanup(_spa_autoclose_cleanup_func)
104
105
/* ========================================================================== */
106
107
#include <stdio.h>
108
109
SPA_DEFINE_AUTOPTR_CLEANUP(FILE, FILE, {
110
spa_clear_ptr(*thing, fclose);
111
})
112
113
/* ========================================================================== */
114
115
#include <dirent.h>
116
117
SPA_DEFINE_AUTOPTR_CLEANUP(DIR, DIR, {
118
spa_clear_ptr(*thing, closedir);
119
})
120
121
#
else
122
123
#define SPA_DEFINE_AUTO_CLEANUP(name, type, ...)
124
#define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...)
125
126
#endif
127
128
#endif
/* SPA_UTILS_CLEANUP_H */
spa
utils
cleanup.h
Generated by
1.17.0