summaryrefslogtreecommitdiff
path: root/extras
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-09-07 11:01:23 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-09-07 11:04:57 -0400
commitcbdf255e255adc0f30b40be296fbbf2f3cd2be80 (patch)
tree49dddc4729a0fa6ecda4336aa4cc5835c841c7c5 /extras
parentcff2f9a3c854fa13067477c797ba926ebcf7dede (diff)
gudev: Deliver ::uevent signal in the thread-default main loop
... that the GUdevClient object was constructed in. This change makes GUdev follow the GLib guidelines and, more importantly, makes it possible to actually use the library in a multi-threaded application. Prior to this patch, signals were emitted in the thread that ran the "default" main loop. Signed-off-by: David Zeuthen <davidz@redhat.com>
Diffstat (limited to 'extras')
-rw-r--r--extras/gudev/gudevclient.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/extras/gudev/gudevclient.c b/extras/gudev/gudevclient.c
index f5f7a198db..e829ca314b 100644
--- a/extras/gudev/gudevclient.c
+++ b/extras/gudev/gudevclient.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
- * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -59,7 +59,7 @@
struct _GUdevClientPrivate
{
- guint watch_id;
+ GSource *watch_source;
struct udev *udev;
struct udev_monitor *monitor;
@@ -117,10 +117,10 @@ g_udev_client_finalize (GObject *object)
{
GUdevClient *client = G_UDEV_CLIENT (object);
- if (client->priv->watch_id != 0)
+ if (client->priv->watch_source != NULL)
{
- g_source_remove (client->priv->watch_id);
- client->priv->watch_id = 0;
+ g_source_destroy (client->priv->watch_source);
+ client->priv->watch_source = NULL;
}
if (client->priv->monitor != NULL)
@@ -229,10 +229,16 @@ g_udev_client_constructed (GObject *object)
{
udev_monitor_enable_receiving (client->priv->monitor);
channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor));
- client->priv->watch_id = g_io_add_watch (channel, G_IO_IN, monitor_event, client);
+ client->priv->watch_source = g_io_create_watch (channel, G_IO_IN);
g_io_channel_unref (channel);
- } else
- client->priv->watch_id = NULL;
+ g_source_set_callback (client->priv->watch_source, (GSourceFunc) monitor_event, client, NULL);
+ g_source_attach (client->priv->watch_source, g_main_context_get_thread_default ());
+ g_source_unref (client->priv->watch_source);
+ }
+ else
+ {
+ client->priv->watch_source = NULL;
+ }
}
if (G_OBJECT_CLASS (g_udev_client_parent_class)->constructed != NULL)
@@ -280,6 +286,10 @@ g_udev_client_class_init (GUdevClientClass *klass)
* @device: Details about the #GUdevDevice the event is for.
*
* Emitted when @client receives an uevent.
+ *
+ * This signal is emitted in the
+ * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+ * of the thread that @client was created in.
*/
signals[UEVENT_SIGNAL] = g_signal_new ("uevent",
G_TYPE_FROM_CLASS (klass),
@@ -310,7 +320,9 @@ g_udev_client_init (GUdevClient *client)
*
* Constructs a #GUdevClient object that can be used to query
* information about devices. Connect to the #GUdevClient::uevent
- * signal to listen for uevents.
+ * signal to listen for uevents. Note that signals are emitted in the
+ * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+ * of the thread that you call this constructor from.
*
* Returns: A new #GUdevClient object. Free with g_object_unref().
*/