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.
This commit is contained in:
parent
f68a26221c
commit
42541a71a2
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue