summaryrefslogtreecommitdiff
path: root/src/core/unit.h
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-04-13 17:25:42 +0200
committerLennart Poettering <lennart@poettering.net>2021-05-25 15:54:19 +0200
commit15ed3c3a188cf7fa5a60ae508fc7a3ed048d2220 (patch)
tree503a41e552a55df8e1cc67096d242d9588f6fcb9 /src/core/unit.h
parent641d3761d45c53000195ed4c6fff7d0d08cdc912 (diff)
downloadsystemd-15ed3c3a188cf7fa5a60ae508fc7a3ed048d2220.tar.gz
core: split dependency types into atoms
Diffstat (limited to 'src/core/unit.h')
-rw-r--r--src/core/unit.h80
1 files changed, 75 insertions, 5 deletions
diff --git a/src/core/unit.h b/src/core/unit.h
index abd8aecc1a..fec5e7a30d 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -102,6 +102,16 @@ typedef union UnitDependencyInfo {
} _packed_;
} UnitDependencyInfo;
+/* Newer LLVM versions don't like implicit casts from large pointer types to smaller enums, hence let's add
+ * explicit type-safe helpers for that. */
+static inline UnitDependency UNIT_DEPENDENCY_FROM_PTR(const void *p) {
+ return PTR_TO_INT(p);
+}
+
+static inline void* UNIT_DEPENDENCY_TO_PTR(UnitDependency d) {
+ return INT_TO_PTR(d);
+}
+
#include "job.h"
struct UnitRef {
@@ -125,11 +135,13 @@ typedef struct Unit {
Set *aliases; /* All the other names. */
- /* For each dependency type we maintain a Hashmap whose key is the Unit* object, and the value encodes why the
- * dependency exists, using the UnitDependencyInfo type */
- Hashmap *dependencies[_UNIT_DEPENDENCY_MAX];
+ /* For each dependency type we can look up another Hashmap with this, whose key is a Unit* object,
+ * and whose value encodes why the dependency exists, using the UnitDependencyInfo type. i.e. a
+ * Hashmap(UnitDependency → Hashmap(Unit* → UnitDependencyInfo)) */
+ Hashmap *dependencies;
- /* Similar, for RequiresMountsFor= path dependencies. The key is the path, the value the UnitDependencyInfo type */
+ /* Similar, for RequiresMountsFor= path dependencies. The key is the path, the value the
+ * UnitDependencyInfo type */
Hashmap *requires_mounts_for;
char *description;
@@ -683,8 +695,15 @@ static inline const UnitVTable* UNIT_VTABLE(const Unit *u) {
#define UNIT_HAS_CGROUP_CONTEXT(u) (UNIT_VTABLE(u)->cgroup_context_offset > 0)
#define UNIT_HAS_KILL_CONTEXT(u) (UNIT_VTABLE(u)->kill_context_offset > 0)
+Unit* unit_has_dependency(const Unit *u, UnitDependencyAtom atom, Unit *other);
+int unit_get_dependency_array(const Unit *u, UnitDependencyAtom atom, Unit ***ret_array);
+
+static inline Hashmap* unit_get_dependencies(Unit *u, UnitDependency d) {
+ return hashmap_get(u->dependencies, UNIT_DEPENDENCY_TO_PTR(d));
+}
+
static inline Unit* UNIT_TRIGGER(Unit *u) {
- return hashmap_first_key(u->dependencies[UNIT_TRIGGERS]);
+ return unit_has_dependency(u, UNIT_ATOM_TRIGGERS, NULL);
}
Unit* unit_new(Manager *m, size_t size);
@@ -990,3 +1009,54 @@ int unit_thaw_vtable_common(Unit *u);
const char* collect_mode_to_string(CollectMode m) _const_;
CollectMode collect_mode_from_string(const char *s) _pure_;
+
+typedef struct UnitForEachDependencyData {
+ /* Stores state for the FOREACH macro below for iterating through all deps that have any of the
+ * specified dependency atom bits set */
+ UnitDependencyAtom match_atom;
+ Hashmap *by_type, *by_unit;
+ void *current_type;
+ Iterator by_type_iterator, by_unit_iterator;
+ Unit **current_unit;
+} UnitForEachDependencyData;
+
+/* Iterates through all dependencies that have a specific atom in the dependency type set. This tries to be
+ * smart: if the atom is unique, we'll directly go to right entry. Otherwise we'll iterate through the
+ * per-dependency type hashmap and match all dep that have the right atom set. */
+#define _UNIT_FOREACH_DEPENDENCY(other, u, ma, data) \
+ for (UnitForEachDependencyData data = { \
+ .match_atom = (ma), \
+ .by_type = (u)->dependencies, \
+ .by_type_iterator = ITERATOR_FIRST, \
+ .current_unit = &(other), \
+ }; \
+ ({ \
+ UnitDependency _dt = _UNIT_DEPENDENCY_INVALID; \
+ bool _found; \
+ \
+ if (data.by_type && ITERATOR_IS_FIRST(data.by_type_iterator)) { \
+ _dt = unit_dependency_from_unique_atom(data.match_atom); \
+ if (_dt >= 0) { \
+ data.by_unit = hashmap_get(data.by_type, UNIT_DEPENDENCY_TO_PTR(_dt)); \
+ data.current_type = UNIT_DEPENDENCY_TO_PTR(_dt); \
+ data.by_type = NULL; \
+ _found = !!data.by_unit; \
+ } \
+ } \
+ if (_dt < 0) \
+ _found = hashmap_iterate(data.by_type, \
+ &data.by_type_iterator, \
+ (void**)&(data.by_unit), \
+ (const void**) &(data.current_type)); \
+ _found; \
+ }); ) \
+ if ((unit_dependency_to_atom(UNIT_DEPENDENCY_FROM_PTR(data.current_type)) & data.match_atom) != 0) \
+ for (data.by_unit_iterator = ITERATOR_FIRST; \
+ hashmap_iterate(data.by_unit, \
+ &data.by_unit_iterator, \
+ NULL, \
+ (const void**) data.current_unit); )
+
+/* Note: this matches deps that have *any* of the atoms specified in match_atom set */
+#define UNIT_FOREACH_DEPENDENCY(other, u, match_atom) \
+ _UNIT_FOREACH_DEPENDENCY(other, u, match_atom, UNIQ_T(data, UNIQ))