summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-03-01 12:43:12 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-03-04 14:16:24 +0100
commit42541a71a2c9560fe37fbef37b868bb53b53aef4 (patch)
treede94866f9fec6af0b88c4750cbf85c526b3a441b
parentf68a26221c3bb93be2841bfcaaaaae5bf0db64ee (diff)
downloadsystemd-42541a71a2c9560fe37fbef37b868bb53b53aef4.tar.gz
bus: make reference counting non-atomic
We had atomic counters, but all other operations were non-serialized. This means that concurrent access to the bus object was only safe if _all_ threads were doing read-only access. Even sending of messages from threads would not be possible, because after sending of the message we usually want to remove it from the send queue in the bus object, which would race. Let's just kill this.
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h11
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c4
-rw-r--r--src/libsystemd/sd-bus/test-bus-cleanup.c17
3 files changed, 11 insertions, 21 deletions
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 04864d4df0..63f1404758 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -13,7 +13,6 @@
#include "hashmap.h"
#include "list.h"
#include "prioq.h"
-#include "refcnt.h"
#include "socket-util.h"
#include "util.h"
@@ -171,15 +170,7 @@ enum bus_auth {
};
struct sd_bus {
- /* We use atomic ref counting here since sd_bus_message
- objects retain references to their originating sd_bus but
- we want to allow them to be processed in a different
- thread. We won't provide full thread safety, but only the
- bare minimum that makes it possible to use sd_bus and
- sd_bus_message objects independently and on different
- threads as long as each object is used only once at the
- same time. */
- RefCount n_ref;
+ unsigned n_ref;
enum bus_state state;
int input_fd, output_fd;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 69f1519976..ba791db4f2 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -236,7 +236,7 @@ _public_ int sd_bus_new(sd_bus **ret) {
return -ENOMEM;
*b = (sd_bus) {
- .n_ref = REFCNT_INIT,
+ .n_ref = 1,
.input_fd = -1,
.output_fd = -1,
.inotify_fd = -1,
@@ -1585,7 +1585,7 @@ void bus_enter_closing(sd_bus *bus) {
bus_set_state(bus, BUS_CLOSING);
}
-DEFINE_PUBLIC_ATOMIC_REF_UNREF_FUNC(sd_bus, sd_bus, bus_free);
+DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_bus, sd_bus, bus_free);
_public_ int sd_bus_is_open(sd_bus *bus) {
assert_return(bus, -EINVAL);
diff --git a/src/libsystemd/sd-bus/test-bus-cleanup.c b/src/libsystemd/sd-bus/test-bus-cleanup.c
index bea722ba06..99d335e3fc 100644
--- a/src/libsystemd/sd-bus/test-bus-cleanup.c
+++ b/src/libsystemd/sd-bus/test-bus-cleanup.c
@@ -7,7 +7,6 @@
#include "bus-internal.h"
#include "bus-message.h"
#include "bus-util.h"
-#include "refcnt.h"
#include "tests.h"
static bool use_system_bus = false;
@@ -16,7 +15,7 @@ static void test_bus_new(void) {
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
assert_se(sd_bus_new(&bus) == 0);
- printf("after new: refcount %u\n", REFCNT_GET(bus->n_ref));
+ assert_se(bus->n_ref == 1);
}
static int test_bus_open(void) {
@@ -32,7 +31,7 @@ static int test_bus_open(void) {
}
assert_se(r >= 0);
- printf("after open: refcount %u\n", REFCNT_GET(bus->n_ref));
+ assert_se(bus->n_ref >= 1); /* we send a hello message when opening, so the count is above 1 */
return 0;
}
@@ -45,10 +44,10 @@ static void test_bus_new_method_call(void) {
assert_se(sd_bus_message_new_method_call(bus, &m, "a.service.name", "/an/object/path", "an.interface.name", "AMethodName") >= 0);
- printf("after message_new_method_call: refcount %u\n", REFCNT_GET(bus->n_ref));
-
+ assert_se(m->n_ref == 1); /* We hold the only reference to the message */
+ assert_se(bus->n_ref >= 2);
sd_bus_flush_close_unref(bus);
- printf("after bus_flush_close_unref: refcount %u\n", m->n_ref);
+ assert_se(m->n_ref == 1);
}
static void test_bus_new_signal(void) {
@@ -59,10 +58,10 @@ static void test_bus_new_signal(void) {
assert_se(sd_bus_message_new_signal(bus, &m, "/an/object/path", "an.interface.name", "Name") >= 0);
- printf("after message_new_signal: refcount %u\n", REFCNT_GET(bus->n_ref));
-
+ assert_se(m->n_ref == 1); /* We hold the only reference to the message */
+ assert_se(bus->n_ref >= 2);
sd_bus_flush_close_unref(bus);
- printf("after bus_flush_close_unref: refcount %u\n", m->n_ref);
+ assert_se(m->n_ref == 1);
}
int main(int argc, char **argv) {