* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: David Zeuthen <davidz@redhat.com>
*/
* @include: gio/gio.h
*
* #GDBusObjectManagerServer is used to export #GDBusObject instances using
- * the standardized <ulink
- * url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">org.freedesktop.DBus.ObjectManager</ulink>
+ * the standardized
+ * [org.freedesktop.DBus.ObjectManager](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
* interface. For example, remote D-Bus clients can get all objects
* and properties in a single call. Additionally, any change in the
* object hierarchy is broadcast using signals. This means that D-Bus
* clients can keep caches up to date by only listening to D-Bus
* signals.
*
- * See #GDBusObjectManagerClient for the client-side code that is intended to
- * be used with #GDBusObjectManagerServer.
+ * See #GDBusObjectManagerClient for the client-side code that is
+ * intended to be used with #GDBusObjectManagerServer or any D-Bus
+ * object implementing the org.freedesktop.DBus.ObjectManager
+ * interface.
*/
typedef struct
static void registration_data_free (RegistrationData *data);
+static void export_all (GDBusObjectManagerServer *manager);
+static void unexport_all (GDBusObjectManagerServer *manager, gboolean only_manager);
+
static void g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager,
RegistrationData *data,
- const gchar *const *interfaces);
+ const gchar *const *interfaces,
+ const gchar *object_path);
static void g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
RegistrationData *data,
const gchar *const *interfaces);
+static gboolean g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer *manager,
+ const gchar *object_path);
+
struct _GDBusObjectManagerServerPrivate
{
+ GMutex lock;
GDBusConnection *connection;
gchar *object_path;
gchar *object_path_ending_in_slash;
static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface);
G_DEFINE_TYPE_WITH_CODE (GDBusObjectManagerServer, g_dbus_object_manager_server, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init));
+ G_ADD_PRIVATE (GDBusObjectManagerServer)
+ G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init))
static void g_dbus_object_manager_server_constructed (GObject *object);
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
+ if (manager->priv->connection != NULL)
+ {
+ unexport_all (manager, TRUE);
+ g_object_unref (manager->priv->connection);
+ }
g_hash_table_unref (manager->priv->map_object_path_to_data);
- if (manager->priv->manager_reg_id > 0)
- g_warn_if_fail (g_dbus_connection_unregister_object (manager->priv->connection, manager->priv->manager_reg_id));
- g_object_unref (manager->priv->connection);
g_free (manager->priv->object_path);
g_free (manager->priv->object_path_ending_in_slash);
+ g_mutex_clear (&manager->priv->lock);
+
if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize != NULL)
G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize (object);
}
static void
-g_dbus_object_manager_server_get_property (GObject *_object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+g_dbus_object_manager_server_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_object);
+ GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
switch (prop_id)
{
case PROP_CONNECTION:
- g_value_set_object (value, g_dbus_object_manager_server_get_connection (manager));
+ g_mutex_lock (&manager->priv->lock);
+ g_value_set_object (value, manager->priv->connection);
+ g_mutex_unlock (&manager->priv->lock);
break;
case PROP_OBJECT_PATH:
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
-g_dbus_object_manager_server_set_property (GObject *_object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+g_dbus_object_manager_server_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_object);
+ GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
switch (prop_id)
{
case PROP_CONNECTION:
- g_assert (manager->priv->connection == NULL);
- g_assert (G_IS_DBUS_CONNECTION (g_value_get_object (value)));
- manager->priv->connection = g_value_dup_object (value);
+ g_dbus_object_manager_server_set_connection (manager, g_value_get_object (value));
break;
case PROP_OBJECT_PATH:
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
G_TYPE_DBUS_CONNECTION,
G_PARAM_READABLE |
G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
-
- g_type_class_add_private (klass, sizeof (GDBusObjectManagerServerPrivate));
}
static void
g_dbus_object_manager_server_init (GDBusObjectManagerServer *manager)
{
- manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
- G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
- GDBusObjectManagerServerPrivate);
+ manager->priv = g_dbus_object_manager_server_get_instance_private (manager);
+ g_mutex_init (&manager->priv->lock);
manager->priv->map_object_path_to_data = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
/**
* g_dbus_object_manager_server_new:
- * @connection: A #GDBusConnection.
* @object_path: The object path to export the manager object at.
*
* Creates a new #GDBusObjectManagerServer object.
*
- * TODO: make it so that the objects are not exported yet -
- * e.g. start()/stop() semantics.
+ * The returned server isn't yet exported on any connection. To do so,
+ * use g_dbus_object_manager_server_set_connection(). Normally you
+ * want to export all of your objects before doing so to avoid <ulink
+ * url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">InterfacesAdded</ulink>
+ * signals being emitted.
*
* Returns: A #GDBusObjectManagerServer object. Free with g_object_unref().
*
* Since: 2.30
*/
GDBusObjectManagerServer *
-g_dbus_object_manager_server_new (GDBusConnection *connection,
- const gchar *object_path)
+g_dbus_object_manager_server_new (const gchar *object_path)
{
- g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
return G_DBUS_OBJECT_MANAGER_SERVER (g_object_new (G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
- "connection", connection,
- "object-path", object_path,
- NULL));
+ "object-path", object_path,
+ NULL));
+}
+
+/**
+ * g_dbus_object_manager_server_set_connection:
+ * @manager: A #GDBusObjectManagerServer.
+ * @connection: (allow-none): A #GDBusConnection or %NULL.
+ *
+ * Exports all objects managed by @manager on @connection. If
+ * @connection is %NULL, stops exporting objects.
+ */
+void
+g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer *manager,
+ GDBusConnection *connection)
+{
+ g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
+ g_return_if_fail (connection == NULL || G_IS_DBUS_CONNECTION (connection));
+
+ g_mutex_lock (&manager->priv->lock);
+
+ if (manager->priv->connection == connection)
+ {
+ g_mutex_unlock (&manager->priv->lock);
+ goto out;
+ }
+
+ if (manager->priv->connection != NULL)
+ {
+ unexport_all (manager, FALSE);
+ g_object_unref (manager->priv->connection);
+ manager->priv->connection = NULL;
+ }
+
+ manager->priv->connection = connection != NULL ? g_object_ref (connection) : NULL;
+ if (manager->priv->connection != NULL)
+ export_all (manager);
+
+ g_mutex_unlock (&manager->priv->lock);
+
+ g_object_notify (G_OBJECT (manager), "connection");
+ out:
+ ;
}
/**
*
* Gets the #GDBusConnection used by @manager.
*
- * Returns: (transfer none): A #GDBusConnection object. Do not free,
- * the object belongs to @manager.
+ * Returns: (transfer full): A #GDBusConnection object or %NULL if
+ * @manager isn't exported on a connection. The returned object should
+ * be freed with g_object_unref().
*
* Since: 2.30
*/
GDBusConnection *
g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager)
{
+ GDBusConnection *ret;
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), NULL);
- return manager->priv->connection;
+ g_mutex_lock (&manager->priv->lock);
+ ret = manager->priv->connection != NULL ? g_object_ref (manager->priv->connection) : NULL;
+ g_mutex_unlock (&manager->priv->lock);
+ return ret;
}
/* ---------------------------------------------------------------------------------------------------- */
static void
registration_data_export_interface (RegistrationData *data,
- GDBusInterfaceSkeleton *interface_skeleton)
+ GDBusInterfaceSkeleton *interface_skeleton,
+ const gchar *object_path)
{
GDBusInterfaceInfo *info;
GError *error;
- const gchar *object_path;
-
- object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
info = g_dbus_interface_skeleton_get_info (interface_skeleton);
error = NULL;
- if (!g_dbus_interface_skeleton_export (interface_skeleton,
- data->manager->priv->connection,
- object_path,
- &error))
+ if (data->manager->priv->connection != NULL)
{
- /* TODO: probably wrong to complain on stderr */
- g_warning ("%s: Error registering object at %s with interface %s: %s",
- G_STRLOC,
- object_path,
- info->name,
- error->message);
- g_error_free (error);
- goto out;
+ if (!g_dbus_interface_skeleton_export (interface_skeleton,
+ data->manager->priv->connection,
+ object_path,
+ &error))
+ {
+ g_warning ("%s: Error registering object at %s with interface %s: %s",
+ G_STRLOC,
+ object_path,
+ info->name,
+ error->message);
+ g_error_free (error);
+ }
}
g_assert (g_hash_table_lookup (data->map_iface_name_to_iface, info->name) == NULL);
/* emit InterfacesAdded on the ObjectManager object */
interfaces[0] = info->name;
interfaces[1] = NULL;
- g_dbus_object_manager_server_emit_interfaces_added (data->manager, data, interfaces);
+ g_dbus_object_manager_server_emit_interfaces_added (data->manager, data, interfaces, object_path);
}
-
- out:
- ;
}
static void
iface = g_hash_table_lookup (data->map_iface_name_to_iface, info->name);
g_assert (iface != NULL);
- g_dbus_interface_skeleton_unexport (iface);
+ if (data->manager->priv->connection != NULL)
+ g_dbus_interface_skeleton_unexport (iface);
g_warn_if_fail (g_hash_table_remove (data->map_iface_name_to_iface, info->name));
gpointer user_data)
{
RegistrationData *data = user_data;
- registration_data_export_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
+ const gchar *object_path;
+ g_mutex_lock (&data->manager->priv->lock);
+ object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
+ registration_data_export_interface (data, G_DBUS_INTERFACE_SKELETON (interface), object_path);
+ g_mutex_unlock (&data->manager->priv->lock);
}
static void
gpointer user_data)
{
RegistrationData *data = user_data;
+ g_mutex_lock (&data->manager->priv->lock);
registration_data_unexport_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
+ g_mutex_unlock (&data->manager->priv->lock);
}
/* ---------------------------------------------------------------------------------------------------- */
g_hash_table_iter_init (&iter, data->map_iface_name_to_iface);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &iface))
- g_dbus_interface_skeleton_unexport (iface);
+ {
+ if (data->manager->priv->connection != NULL)
+ g_dbus_interface_skeleton_unexport (iface);
+ }
g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_added), data);
g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_removed), data);
/* ---------------------------------------------------------------------------------------------------- */
-/**
- * g_dbus_object_manager_server_export:
- * @manager: A #GDBusObjectManagerServer.
- * @object: A #GDBusObjectSkeleton.
- *
- * Exports @object on @manager.
- *
- * If there is already a #GDBusObject exported at the object path,
- * then the old object is removed.
- *
- * The object path for @object must be in the hierarchy rooted by the
- * object path for @manager.
- *
- * Note that @manager will take a reference on @object for as long as
- * it is exported.
- *
- * Since: 2.30
- */
-void
-g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
- GDBusObjectSkeleton *object)
+static void
+g_dbus_object_manager_server_export_unlocked (GDBusObjectManagerServer *manager,
+ GDBusObjectSkeleton *object,
+ const gchar *object_path)
{
RegistrationData *data;
GList *existing_interfaces;
GList *l;
GPtrArray *interface_names;
- const gchar *object_path;
-
- object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
g_return_if_fail (G_IS_DBUS_OBJECT (object));
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
if (data != NULL)
- g_dbus_object_manager_server_unexport (manager, object_path);
+ g_dbus_object_manager_server_unexport_unlocked (manager, object_path);
data = g_new0 (RegistrationData, 1);
data->object = g_object_ref (object);
for (l = existing_interfaces; l != NULL; l = l->next)
{
GDBusInterfaceSkeleton *interface_skeleton = G_DBUS_INTERFACE_SKELETON (l->data);
- registration_data_export_interface (data, interface_skeleton);
+ registration_data_export_interface (data, interface_skeleton, object_path);
g_ptr_array_add (interface_names, g_dbus_interface_skeleton_get_info (interface_skeleton)->name);
}
- g_list_foreach (existing_interfaces, (GFunc) g_object_unref, NULL);
- g_list_free (existing_interfaces);
+ g_list_free_full (existing_interfaces, g_object_unref);
g_ptr_array_add (interface_names, NULL);
data->exported = TRUE;
/* now emit InterfacesAdded() for all the interfaces */
- g_dbus_object_manager_server_emit_interfaces_added (manager, data, (const gchar *const *) interface_names->pdata);
+ g_dbus_object_manager_server_emit_interfaces_added (manager, data, (const gchar *const *) interface_names->pdata, object_path);
g_ptr_array_unref (interface_names);
g_hash_table_insert (manager->priv->map_object_path_to_data,
}
/**
+ * g_dbus_object_manager_server_export:
+ * @manager: A #GDBusObjectManagerServer.
+ * @object: A #GDBusObjectSkeleton.
+ *
+ * Exports @object on @manager.
+ *
+ * If there is already a #GDBusObject exported at the object path,
+ * then the old object is removed.
+ *
+ * The object path for @object must be in the hierarchy rooted by the
+ * object path for @manager.
+ *
+ * Note that @manager will take a reference on @object for as long as
+ * it is exported.
+ *
+ * Since: 2.30
+ */
+void
+g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
+ GDBusObjectSkeleton *object)
+{
+ g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
+ g_mutex_lock (&manager->priv->lock);
+ g_dbus_object_manager_server_export_unlocked (manager, object,
+ g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+ g_mutex_unlock (&manager->priv->lock);
+}
+
+/**
* g_dbus_object_manager_server_export_uniquely:
* @manager: A #GDBusObjectManagerServer.
* @object: An object.
*
* Like g_dbus_object_manager_server_export() but appends a string of
- * the form <literal>_N</literal> (with N being a natural number) to
- * @object<!-- -->'s object path if an object with the given path
- * already exists. As such, the #GDBusObjectProxy:object-path property
- * of @object may be modified.
+ * the form _N (with N being a natural number) to @object's object path
+ * if an object with the given path already exists. As such, the
+ * #GDBusObjectProxy:g-object-path property of @object may be modified.
*
* Since: 2.30
*/
g_return_if_fail (G_IS_DBUS_OBJECT (object));
g_return_if_fail (g_str_has_prefix (orig_object_path, manager->priv->object_path_ending_in_slash));
+ g_mutex_lock (&manager->priv->lock);
+
object_path = g_strdup (orig_object_path);
count = 1;
modified = FALSE;
modified = TRUE;
}
+ g_dbus_object_manager_server_export_unlocked (manager, object, object_path);
+
+ g_mutex_unlock (&manager->priv->lock);
+
if (modified)
g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path);
- g_dbus_object_manager_server_export (manager, object);
-
g_free (object_path);
g_free (orig_object_path);
+
}
/**
- * g_dbus_object_manager_server_unexport:
+ * g_dbus_object_manager_server_is_exported:
* @manager: A #GDBusObjectManagerServer.
- * @object_path: An object path.
- *
- * If @manager has an object at @path, removes the object. Otherwise
- * does nothing.
+ * @object: An object.
*
- * Note that @object_path must be in the hierarchy rooted by the
- * object path for @manager.
+ * Returns whether @object is currently exported on @manager.
*
- * Returns: %TRUE if object at @object_path was removed, %FALSE otherwise.
+ * Returns: %TRUE if @object is exported
*
- * Since: 2.30
- */
+ * Since: 2.34
+ **/
gboolean
-g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager,
- const gchar *object_path)
+g_dbus_object_manager_server_is_exported (GDBusObjectManagerServer *manager,
+ GDBusObjectSkeleton *object)
+{
+ RegistrationData *data = NULL;
+ const gchar *object_path;
+ gboolean object_is_exported;
+
+ g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
+ g_return_val_if_fail (G_IS_DBUS_OBJECT (object), FALSE);
+
+ g_mutex_lock (&manager->priv->lock);
+
+ object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
+ if (object_path != NULL)
+ data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
+ object_is_exported = (data != NULL);
+
+ g_mutex_unlock (&manager->priv->lock);
+
+ return object_is_exported;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer *manager,
+ const gchar *object_path)
{
RegistrationData *data;
gboolean ret;
return ret;
}
+/**
+ * g_dbus_object_manager_server_unexport:
+ * @manager: A #GDBusObjectManagerServer.
+ * @object_path: An object path.
+ *
+ * If @manager has an object at @path, removes the object. Otherwise
+ * does nothing.
+ *
+ * Note that @object_path must be in the hierarchy rooted by the
+ * object path for @manager.
+ *
+ * Returns: %TRUE if object at @object_path was removed, %FALSE otherwise.
+ *
+ * Since: 2.30
+ */
+gboolean
+g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager,
+ const gchar *object_path)
+{
+ gboolean ret;
+ g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
+ g_mutex_lock (&manager->priv->lock);
+ ret = g_dbus_object_manager_server_unexport_unlocked (manager, object_path);
+ g_mutex_unlock (&manager->priv->lock);
+ return ret;
+}
+
/* ---------------------------------------------------------------------------------------------------- */
GHashTableIter object_iter;
RegistrationData *data;
+ g_mutex_lock (&manager->priv->lock);
+
if (g_strcmp0 (method_name, "GetManagedObjects") == 0)
{
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{oa{sa{sv}}}"));
g_hash_table_iter_init (&interface_iter, data->map_iface_name_to_iface);
while (g_hash_table_iter_next (&interface_iter, NULL, (gpointer) &iface))
{
- g_variant_builder_add_value (&interfaces_builder,
- g_variant_new ("{s@a{sv}}",
- g_dbus_interface_skeleton_get_info (iface)->name,
- g_dbus_interface_skeleton_get_properties (iface)));
+ GVariant *properties = g_dbus_interface_skeleton_get_properties (iface);
+ g_variant_builder_add (&interfaces_builder, "{s@a{sv}}",
+ g_dbus_interface_skeleton_get_info (iface)->name,
+ properties);
+ g_variant_unref (properties);
}
iter_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
g_variant_builder_add (&array_builder,
"Unknown method %s - only GetManagedObjects() is supported",
method_name);
}
+ g_mutex_unlock (&manager->priv->lock);
}
static const GDBusInterfaceVTable manager_interface_vtable =
g_dbus_object_manager_server_constructed (GObject *object)
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
- GError *error;
- error = NULL;
- manager->priv->manager_reg_id = g_dbus_connection_register_object (manager->priv->connection,
- manager->priv->object_path,
- (GDBusInterfaceInfo *) &manager_interface_info,
- &manager_interface_vtable,
- manager,
- NULL, /* user_data_free_func */
- &error);
- if (manager->priv->manager_reg_id == 0)
- {
- /* TODO: probably wrong to complain on stderr */
- g_warning ("%s: Error registering manager at %s: %s",
- G_STRLOC,
- manager->priv->object_path,
- error->message);
- g_error_free (error);
- }
+ if (manager->priv->connection != NULL)
+ export_all (manager);
if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed != NULL)
G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed (object);
static void
g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager,
- RegistrationData *data,
- const gchar *const *interfaces)
+ RegistrationData *data,
+ const gchar *const *interfaces,
+ const gchar *object_path)
{
GVariantBuilder array_builder;
GError *error;
guint n;
- const gchar *object_path;
+
+ if (data->manager->priv->connection == NULL)
+ goto out;
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{sa{sv}}"));
for (n = 0; interfaces[n] != NULL; n++)
{
GDBusInterfaceSkeleton *iface;
+ GVariant *properties;
+
iface = g_hash_table_lookup (data->map_iface_name_to_iface, interfaces[n]);
g_assert (iface != NULL);
- g_variant_builder_add_value (&array_builder,
- g_variant_new ("{s@a{sv}}",
- interfaces[n],
- g_dbus_interface_skeleton_get_properties (iface)));
+ properties = g_dbus_interface_skeleton_get_properties (iface);
+ g_variant_builder_add (&array_builder, "{s@a{sv}}", interfaces[n], properties);
+ g_variant_unref (properties);
}
error = NULL;
- object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
g_dbus_connection_emit_signal (data->manager->priv->connection,
NULL, /* destination_bus_name */
manager->priv->object_path,
&array_builder),
&error);
g_assert_no_error (error);
+ out:
+ ;
}
static void
g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
- RegistrationData *data,
- const gchar *const *interfaces)
+ RegistrationData *data,
+ const gchar *const *interfaces)
{
GVariantBuilder array_builder;
GError *error;
guint n;
const gchar *object_path;
+ if (data->manager->priv->connection == NULL)
+ goto out;
+
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as"));
for (n = 0; interfaces[n] != NULL; n++)
g_variant_builder_add (&array_builder, "s", interfaces[n]);
&array_builder),
&error);
g_assert_no_error (error);
+ out:
+ ;
}
/* ---------------------------------------------------------------------------------------------------- */
GHashTableIter iter;
RegistrationData *data;
+ g_mutex_lock (&manager->priv->lock);
+
ret = NULL;
g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
ret = g_list_prepend (ret, g_object_ref (data->object));
}
+ g_mutex_unlock (&manager->priv->lock);
+
return ret;
}
RegistrationData *data;
ret = NULL;
+
+ g_mutex_lock (&manager->priv->lock);
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
if (data != NULL)
ret = g_object_ref (data->object);
+ g_mutex_unlock (&manager->priv->lock);
+
return ret;
}
iface->get_object = g_dbus_object_manager_server_get_object;
iface->get_interface = g_dbus_object_manager_server_get_interface;
}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+export_all (GDBusObjectManagerServer *manager)
+{
+ GHashTableIter iter;
+ const gchar *object_path;
+ RegistrationData *data;
+ GHashTableIter iface_iter;
+ GDBusInterfaceSkeleton *iface;
+ GError *error;
+
+ g_return_if_fail (manager->priv->connection != NULL);
+
+ error = NULL;
+ g_warn_if_fail (manager->priv->manager_reg_id == 0);
+ manager->priv->manager_reg_id = g_dbus_connection_register_object (manager->priv->connection,
+ manager->priv->object_path,
+ (GDBusInterfaceInfo *) &manager_interface_info,
+ &manager_interface_vtable,
+ manager,
+ NULL, /* user_data_free_func */
+ &error);
+ if (manager->priv->manager_reg_id == 0)
+ {
+ g_warning ("%s: Error registering manager at %s: %s",
+ G_STRLOC,
+ manager->priv->object_path,
+ error->message);
+ g_error_free (error);
+ }
+
+ g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
+ while (g_hash_table_iter_next (&iter, (gpointer) &object_path, (gpointer) &data))
+ {
+ g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface);
+ while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface))
+ {
+ g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) == NULL);
+ error = NULL;
+ if (!g_dbus_interface_skeleton_export (iface,
+ manager->priv->connection,
+ object_path,
+ &error))
+ {
+ g_warning ("%s: Error registering object at %s with interface %s: %s",
+ G_STRLOC,
+ object_path,
+ g_dbus_interface_skeleton_get_info (iface)->name,
+ error->message);
+ g_error_free (error);
+ }
+ }
+ }
+}
+
+static void
+unexport_all (GDBusObjectManagerServer *manager, gboolean only_manager)
+{
+ GHashTableIter iter;
+ RegistrationData *data;
+ GHashTableIter iface_iter;
+ GDBusInterfaceSkeleton *iface;
+
+ g_return_if_fail (manager->priv->connection != NULL);
+
+ g_warn_if_fail (manager->priv->manager_reg_id > 0);
+ if (manager->priv->manager_reg_id > 0)
+ {
+ g_warn_if_fail (g_dbus_connection_unregister_object (manager->priv->connection,
+ manager->priv->manager_reg_id));
+ manager->priv->manager_reg_id = 0;
+ }
+ if (only_manager)
+ goto out;
+
+ g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
+ {
+ g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface);
+ while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface))
+ {
+ g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) != NULL);
+ g_dbus_interface_skeleton_unexport (iface);
+ }
+ }
+ out:
+ ;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */