In preparation for adopting forward declarations to reduce unnecessary transitive includes across the tree, let's introduce a forward.h header with forward declarations for all libc, libsystemd, basic and shared types. Additionally, this header exports all basic integer types and errno constants, as well as all macros including assertions macros. These header files contain types often used in headers and are always included in every source file one way or another anyway. To avoid having to include memory-util.h and alloc-util.h in forward.h, we split off the parts we need from both into cleanup-util.h and only include cleanup-util.h in forward.h. To keep this commit self-contained, we include cleanup-fundamental.h and cleanup-util.h from the headers that originally contained the same macros. We'll remove these again in a later commit that optimizes the includes in src/basic and src/fundamental. Split out of #37364
82 lines
3.9 KiB
C
82 lines
3.9 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
#pragma once
|
|
|
|
#include "cleanup-fundamental.h" /* IWYU pragma: export */
|
|
|
|
typedef void (*free_func_t)(void *p);
|
|
typedef void* (*mfree_func_t)(void *p);
|
|
|
|
#define free_and_replace_full(a, b, free_func) \
|
|
({ \
|
|
typeof(a)* _a = &(a); \
|
|
typeof(b)* _b = &(b); \
|
|
free_func(*_a); \
|
|
*_a = *_b; \
|
|
*_b = NULL; \
|
|
0; \
|
|
})
|
|
|
|
/* This is similar to free_and_replace_full(), but NULL is not assigned to 'b', and its reference counter is
|
|
* increased. */
|
|
#define unref_and_replace_full(a, b, ref_func, unref_func) \
|
|
({ \
|
|
typeof(a)* _a = &(a); \
|
|
typeof(b) _b = ref_func(b); \
|
|
unref_func(*_a); \
|
|
*_a = _b; \
|
|
0; \
|
|
})
|
|
|
|
#define _DEFINE_TRIVIAL_REF_FUNC(type, name, scope) \
|
|
scope type *name##_ref(type *p) { \
|
|
if (!p) \
|
|
return NULL; \
|
|
\
|
|
/* For type check. */ \
|
|
unsigned *q = &p->n_ref; \
|
|
assert(*q > 0); \
|
|
assert_se(*q < UINT_MAX); \
|
|
\
|
|
(*q)++; \
|
|
return p; \
|
|
}
|
|
|
|
#define _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, scope) \
|
|
scope type *name##_unref(type *p) { \
|
|
if (!p) \
|
|
return NULL; \
|
|
\
|
|
assert(p->n_ref > 0); \
|
|
p->n_ref--; \
|
|
if (p->n_ref > 0) \
|
|
return NULL; \
|
|
\
|
|
return free_func(p); \
|
|
}
|
|
|
|
#define DEFINE_TRIVIAL_REF_FUNC(type, name) \
|
|
_DEFINE_TRIVIAL_REF_FUNC(type, name,)
|
|
#define DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name) \
|
|
_DEFINE_TRIVIAL_REF_FUNC(type, name, static)
|
|
#define DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name) \
|
|
_DEFINE_TRIVIAL_REF_FUNC(type, name, _public_)
|
|
|
|
#define DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func) \
|
|
_DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func,)
|
|
#define DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func) \
|
|
_DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, static)
|
|
#define DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func) \
|
|
_DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, _public_)
|
|
|
|
#define DEFINE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \
|
|
DEFINE_TRIVIAL_REF_FUNC(type, name); \
|
|
DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func);
|
|
|
|
#define DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \
|
|
DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name); \
|
|
DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func);
|
|
|
|
#define DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \
|
|
DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name); \
|
|
DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func);
|