diff --git a/man/sd_bus_new.xml b/man/sd_bus_new.xml
index 1bc011d70a1..cc08e6be17d 100644
--- a/man/sd_bus_new.xml
+++ b/man/sd_bus_new.xml
@@ -23,6 +23,8 @@
sd_bus_ref
sd_bus_unref
sd_bus_unrefp
+ sd_bus_close_unref
+ sd_bus_close_unrefp
sd_bus_flush_close_unref
sd_bus_flush_close_unrefp
@@ -49,8 +51,8 @@
- void sd_bus_unrefp
- sd_bus **busp
+ sd_bus *sd_bus_close_unref
+ sd_bus *bus
@@ -58,6 +60,16 @@
sd_bus *bus
+
+ void sd_bus_unrefp
+ sd_bus **busp
+
+
+
+ void sd_bus_close_unrefp
+ sd_bus **busp
+
+
void sd_bus_flush_close_unrefp
sd_bus **busp
@@ -124,17 +136,25 @@
execute no operation if that is NULL.
- sd_bus_flush_close_unref() is similar to sd_bus_unref(), but first
- executes sd_bus_flush3 as well
- as sd_bus_close3, ensuring that
- any pending messages are properly flushed out before the reference to the connection is dropped and possibly the
- object freed. This call is particularly useful immediately before exiting from a program as it ensures that any
- pending outgoing messages are written out, and unprocessed but queued incoming messages released before the
- connection is terminated and released.
+ sd_bus_close_unref() is similar to sd_bus_unref(), but
+ first executes
+ sd_bus_close3,
+ ensuring that the connection is terminated before the reference to the connection is dropped and possibly
+ the object freed.
- sd_bus_flush_close_unrefp() is similar to
- sd_bus_flush_close_unref(), but may be used in GCC's and LLVM's Clean-up Variable Attribute,
- see above.
+ sd_bus_flush_close_unref() is similar to sd_bus_unref(),
+ but first executes
+ sd_bus_flush3 as well
+ as sd_bus_close3,
+ ensuring that any pending messages are synchronously flushed out before the reference to the connection
+ is dropped and possibly the object freed. This call is particularly useful immediately before exiting
+ from a program as it ensures that any pending outgoing messages are written out, and unprocessed but
+ queued incoming messages released before the connection is terminated and released.
+
+ sd_bus_close_unrefp() is similar to
+ sd_bus_close_unref(), but may be used in GCC's and LLVM's Clean-up Variable
+ Attribute, see above. Similarly, sd_bus_flush_close_unrefp() is similar to
+ sd_bus_flush_close_unref().
diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c
index 96b4177495f..08d9e70c960 100644
--- a/src/busctl/busctl.c
+++ b/src/busctl/busctl.c
@@ -67,7 +67,7 @@ static int json_transform_message(sd_bus_message *m, JsonVariant **ret);
static void json_dump_with_flags(JsonVariant *v, FILE *f);
static int acquire_bus(bool set_monitor, sd_bus **ret) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
int r;
r = sd_bus_new(&bus);
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 5908ad792a7..255b86e7a41 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -611,7 +611,7 @@ static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
}
static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
_cleanup_close_ int nfd = -1;
Manager *m = userdata;
sd_id128_t id;
@@ -876,7 +876,7 @@ static int bus_setup_api(Manager *m, sd_bus *bus) {
}
int bus_init_api(Manager *m) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
int r;
if (m->api_bus)
@@ -940,7 +940,7 @@ static int bus_setup_system(Manager *m, sd_bus *bus) {
}
int bus_init_system(Manager *m) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
int r;
if (m->system_bus)
@@ -1080,8 +1080,7 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
sd_bus_flush(*bus);
/* And destroy the object */
- sd_bus_close(*bus);
- *bus = sd_bus_unref(*bus);
+ *bus = sd_bus_close_unref(*bus);
}
void bus_done_api(Manager *m) {
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
index c60d4bd740a..260dc2eb618 100644
--- a/src/initctl/initctl.c
+++ b/src/initctl/initctl.c
@@ -233,12 +233,8 @@ static void server_done(Server *s) {
while (s->fifos)
fifo_free(s->fifos);
- safe_close(s->epoll_fd);
-
- if (s->bus) {
- sd_bus_flush(s->bus);
- sd_bus_unref(s->bus);
- }
+ s->epoll_fd = safe_close(s->epoll_fd);
+ s->bus = sd_bus_flush_close_unref(s->bus);
}
static int server_init(Server *s, unsigned n_sockets) {
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 96e63477956..a6748ceb209 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -671,3 +671,8 @@ global:
sd_event_source_get_floating;
sd_event_source_set_floating;
} LIBSYSTEMD_239;
+
+LIBSYSTEMD_241 {
+global:
+ sd_bus_close_unref;
+} LIBSYSTEMD_240;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 3b00bc81572..1ff858f32d3 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -1556,17 +1556,24 @@ _public_ void sd_bus_close(sd_bus *bus) {
bus_close_inotify_fd(bus);
}
+_public_ sd_bus *sd_bus_close_unref(sd_bus *bus) {
+ if (!bus)
+ return NULL;
+
+ sd_bus_close(bus);
+
+ return sd_bus_unref(bus);
+}
+
_public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
if (!bus)
return NULL;
/* Have to do this before flush() to prevent hang */
bus_kill_exec(bus);
-
sd_bus_flush(bus);
- sd_bus_close(bus);
- return sd_bus_unref(bus);
+ return sd_bus_close_unref(bus);
}
void bus_enter_closing(sd_bus *bus) {
diff --git a/src/login/logind.c b/src/login/logind.c
index 8d85de9b43c..95ec0a57c60 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -146,7 +146,7 @@ static Manager* manager_unref(Manager *m) {
bus_verify_polkit_async_registry_free(m->polkit_registry);
- sd_bus_unref(m->bus);
+ sd_bus_flush_close_unref(m->bus);
sd_event_unref(m->event);
safe_close(m->reserve_vt_fd);
diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c
index 5e58e4baadb..eb66e18de1c 100644
--- a/src/login/user-runtime-dir.c
+++ b/src/login/user-runtime-dir.c
@@ -22,7 +22,7 @@
static int acquire_runtime_dir_size(uint64_t *ret) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r;
r = sd_bus_default_system(&bus);
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 48270b3709a..7a558df8983 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -454,7 +454,7 @@ static int container_bus_new(Machine *m, sd_bus_error *error, sd_bus **ret) {
break;
case MACHINE_CONTAINER: {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
char *address;
r = sd_bus_new(&bus);
diff --git a/src/machine/machined.c b/src/machine/machined.c
index 9f23e369a46..0b92b1c6ee2 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -81,7 +81,7 @@ static Manager* manager_unref(Manager *m) {
bus_verify_polkit_async_registry_free(m->polkit_registry);
- sd_bus_unref(m->bus);
+ sd_bus_flush_close_unref(m->bus);
sd_event_unref(m->event);
return mfree(m);
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 81c81f18af0..c8d369e2a0f 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -1456,7 +1456,7 @@ void manager_free(Manager *m) {
sd_device_monitor_unref(m->device_monitor);
- sd_bus_unref(m->bus);
+ sd_bus_flush_close_unref(m->bus);
free(m->dynamic_timezone);
free(m->dynamic_hostname);
diff --git a/src/portable/portabled.c b/src/portable/portabled.c
index 63fc3404691..49a359fd315 100644
--- a/src/portable/portabled.c
+++ b/src/portable/portabled.c
@@ -53,7 +53,7 @@ static Manager* manager_unref(Manager *m) {
bus_verify_polkit_async_registry_free(m->polkit_registry);
- sd_bus_unref(m->bus);
+ sd_bus_flush_close_unref(m->bus);
sd_event_unref(m->event);
return mfree(m);
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index b7dc09ae370..b3d35c83413 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -689,7 +689,7 @@ Manager *manager_free(Manager *m) {
manager_mdns_stop(m);
manager_dns_stub_stop(m);
- sd_bus_unref(m->bus);
+ sd_bus_flush_close_unref(m->bus);
sd_event_source_unref(m->sigusr1_event_source);
sd_event_source_unref(m->sigusr2_event_source);
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 976643e4ce0..cbcf698e965 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -559,7 +559,7 @@ int bus_check_peercred(sd_bus *c) {
}
int bus_connect_system_systemd(sd_bus **_bus) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
int r;
assert(_bus);
@@ -592,7 +592,7 @@ int bus_connect_system_systemd(sd_bus **_bus) {
}
int bus_connect_user_systemd(sd_bus **_bus) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
_cleanup_free_ char *ee = NULL;
const char *e;
int r;
@@ -1279,7 +1279,7 @@ int bus_map_all_properties(
}
int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **ret) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
int r;
assert(transport >= 0);
@@ -1666,7 +1666,7 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) {
}
int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
const char *e;
int r;
diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c
index 3a21aa4aed0..7060897ab7b 100644
--- a/src/stdio-bridge/stdio-bridge.c
+++ b/src/stdio-bridge/stdio-bridge.c
@@ -91,7 +91,7 @@ static int parse_argv(int argc, char *argv[]) {
}
static int run(int argc, char *argv[]) {
- _cleanup_(sd_bus_unrefp) sd_bus *a = NULL, *b = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *a = NULL, *b = NULL;
sd_id128_t server_id;
bool is_unix;
int r, in_fd, out_fd;
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 4c1acab9f3a..129cc933288 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -170,6 +170,7 @@ void sd_bus_close(sd_bus *bus);
sd_bus *sd_bus_ref(sd_bus *bus);
sd_bus *sd_bus_unref(sd_bus *bus);
+sd_bus *sd_bus_close_unref(sd_bus *bus);
sd_bus *sd_bus_flush_close_unref(sd_bus *bus);
void sd_bus_default_flush_close(void);
@@ -493,6 +494,7 @@ int sd_bus_track_get_destroy_callback(sd_bus_track *s, sd_bus_destroy_t *ret);
/* Define helpers so that __attribute__((cleanup(sd_bus_unrefp))) and similar may be used. */
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus, sd_bus_unref);
+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus, sd_bus_close_unref);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus, sd_bus_flush_close_unref);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus_slot, sd_bus_slot_unref);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus_message, sd_bus_message_unref);
diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index 4b0696f3a3e..b3bd7235c90 100644
--- a/src/timesync/timesyncd-manager.c
+++ b/src/timesync/timesyncd-manager.c
@@ -937,7 +937,7 @@ void manager_free(Manager *m) {
sd_resolve_unref(m->resolve);
sd_event_unref(m->event);
- sd_bus_unref(m->bus);
+ sd_bus_flush_close_unref(m->bus);
free(m);
}