summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2017-11-06 16:25:42 +0000
committerSimon McVittie <smcv@collabora.com>2017-12-11 16:03:21 +0000
commita0fd44f83d21cce3af1238edbfbe12b5987617e1 (patch)
treeaff0cced4dc9944bde5634067fdaaacd0bae42f5
parenta65f0da9b718b2cd9e4299541ff5adbeb1623340 (diff)
bus/containers: Give each instance a list of all its connections
Reviewed-by: Philip Withnall <withnall@endlessm.com> [smcv: Fix minor conflict] Signed-off-by: Simon McVittie <smcv@collabora.com> Bug: https://bugs.freedesktop.org/show_bug.cgi?id=101354
-rw-r--r--bus/containers.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/bus/containers.c b/bus/containers.c
index e30feb37..91806dbe 100644
--- a/bus/containers.c
+++ b/bus/containers.c
@@ -55,6 +55,9 @@ typedef struct
BusContainers *containers;
DBusServer *server;
DBusConnection *creator;
+ /* List of owned DBusConnection, removed when the DBusConnection is
+ * removed from the bus */
+ DBusList *connections;
unsigned long uid;
} BusContainerInstance;
@@ -219,6 +222,11 @@ bus_container_instance_unref (BusContainerInstance *self)
* BusContainerInstance */
_dbus_assert (self->server == NULL);
+ /* Similarly, as long as there are connections, the BusContainerInstance
+ * can't be freed, because each connection holds a reference to the
+ * BusContainerInstance */
+ _dbus_assert (self->connections == NULL);
+
creator_data = dbus_connection_get_data (self->creator,
container_creator_data_slot);
_dbus_assert (creator_data != NULL);
@@ -376,6 +384,11 @@ bus_container_instance_lost_connection (BusContainerInstance *instance,
bus_container_instance_ref (instance);
dbus_connection_ref (connection);
+ /* This is O(n), but we don't expect to have many connections per
+ * container instance. */
+ if (_dbus_list_remove (&instance->connections, connection))
+ dbus_connection_unref (connection);
+
dbus_connection_set_data (connection, contained_data_slot, NULL, NULL);
dbus_connection_unref (connection);
@@ -398,6 +411,16 @@ new_connection_cb (DBusServer *server,
return;
}
+ if (_dbus_list_append (&instance->connections, new_connection))
+ {
+ dbus_connection_ref (new_connection);
+ }
+ else
+ {
+ bus_container_instance_lost_connection (instance, new_connection);
+ return;
+ }
+
/* If this fails it logs a warning, so we don't need to do that.
* We don't know how to undo this, so do it last (apart from things that
* cannot fail) */
@@ -819,6 +842,7 @@ bus_containers_remove_connection (BusContainers *self,
{
#ifdef DBUS_ENABLE_CONTAINERS
BusContainerCreatorData *creator_data;
+ BusContainerInstance *instance;
dbus_connection_ref (connection);
creator_data = dbus_connection_get_data (connection,
@@ -833,7 +857,7 @@ bus_containers_remove_connection (BusContainers *self,
iter != NULL;
iter = next)
{
- BusContainerInstance *instance = iter->data;
+ instance = iter->data;
/* Remember where we got to before we do something that might free
* iter and instance */
@@ -847,6 +871,18 @@ bus_containers_remove_connection (BusContainers *self,
}
}
+ instance = dbus_connection_get_data (connection, contained_data_slot);
+
+ if (instance != NULL)
+ {
+ bus_container_instance_ref (instance);
+
+ if (_dbus_list_remove (&instance->connections, connection))
+ dbus_connection_unref (connection);
+
+ bus_container_instance_unref (instance);
+ }
+
dbus_connection_unref (connection);
#endif /* DBUS_ENABLE_CONTAINERS */
}