chiark / gitweb /
Merge branch 'docs/udev.xml' of git://github.com/mfwitten/udev
[elogind.git] / extras / gudev / gudevclient.c
index f5f7a198db1a77449045b33f2ea51fe4b654cbd9..97b951adcd421e559c4a2d7b3b822eb95dd01f1d 100644 (file)
@@ -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
  * memory) and as such there are no asynchronous versions of the
  * provided methods.
  *
- * To get information about a device, use
+ * To get #GUdevDevice objects, use
  * g_udev_client_query_by_subsystem(),
  * g_udev_client_query_by_device_number(),
  * g_udev_client_query_by_device_file(),
- * g_udev_client_query_by_sysfs_path() or
- * g_udev_client_query_by_subsystem_and_name().
+ * g_udev_client_query_by_sysfs_path(),
+ * g_udev_client_query_by_subsystem_and_name()
+ * or the #GUdevEnumerator type.
  *
  * To listen to uevents, connect to the #GUdevClient::uevent signal.
  */
 
 struct _GUdevClientPrivate
 {
-  guint watch_id;
+  GSource *watch_source;
   struct udev *udev;
   struct udev_monitor *monitor;
 
@@ -117,10 +118,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 +230,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 +287,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),
@@ -306,11 +317,13 @@ g_udev_client_init (GUdevClient *client)
 
 /**
  * g_udev_client_new:
- * @subsystems: (allow-none): A %NULL terminated string array of subsystems to listen for uevents on, %NULL to not listen on uevents at all, or an empty array to listen to uevents on all subsystems. See the documentation for the #GUdevClient:subsystems property for details on this parameter.
+ * @subsystems: (array zero-terminated=1) (element-type utf8) (transfer none) (allow-none): A %NULL terminated string array of subsystems to listen for uevents on, %NULL to not listen on uevents at all, or an empty array to listen to uevents on all subsystems. See the documentation for the #GUdevClient:subsystems property for details on this parameter.
  *
  * 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().
  */
@@ -327,7 +340,7 @@ g_udev_client_new (const gchar * const *subsystems)
  *
  * Gets all devices belonging to @subsystem.
  *
- * Returns: (element-type GUdevDevice): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
+ * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
  */
 GList *
 g_udev_client_query_by_subsystem (GUdevClient  *client,
@@ -380,7 +393,7 @@ g_udev_client_query_by_subsystem (GUdevClient  *client,
  *
  * Looks up a device for a type and device number.
  *
- * Returns: A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
  */
 GUdevDevice *
 g_udev_client_query_by_device_number (GUdevClient      *client,
@@ -412,7 +425,7 @@ g_udev_client_query_by_device_number (GUdevClient      *client,
  *
  * Looks up a device for a device file.
  *
- * Returns: A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
  */
 GUdevDevice *
 g_udev_client_query_by_device_file (GUdevClient  *client,
@@ -448,7 +461,7 @@ g_udev_client_query_by_device_file (GUdevClient  *client,
  *
  * Looks up a device for a sysfs path.
  *
- * Returns: A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
  */
 GUdevDevice *
 g_udev_client_query_by_sysfs_path (GUdevClient  *client,
@@ -480,7 +493,7 @@ g_udev_client_query_by_sysfs_path (GUdevClient  *client,
  *
  * Looks up a device for a subsystem and name.
  *
- * Returns: A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
  */
 GUdevDevice *
 g_udev_client_query_by_subsystem_and_name (GUdevClient  *client,
@@ -506,3 +519,10 @@ g_udev_client_query_by_subsystem_and_name (GUdevClient  *client,
   return device;
 }
 
+struct udev *
+_g_udev_client_get_udev (GUdevClient *client)
+{
+  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+  return client->priv->udev;
+}
+