chiark / gitweb /
gudev: silent gtk-doc warnings
[elogind.git] / extras / gudev / gudevclient.c
index fa31f70bf5b278381892e62414ada57c8ce12f98..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;
 
@@ -93,6 +94,8 @@ monitor_event (GIOChannel *source,
   GUdevDevice *device;
   struct udev_device *udevice;
 
+  if (client->priv->monitor == NULL)
+    goto out;
   udevice = udev_monitor_receive_device (client->priv->monitor);
   if (udevice == NULL)
     goto out;
@@ -115,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)
@@ -216,17 +219,27 @@ g_udev_client_constructed (GObject *object)
               *s = '\0';
             }
 
-          udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype);
+          if (client->priv->monitor != NULL)
+              udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype);
 
           g_free (subsystem);
         }
 
       /* listen to events, and buffer them */
-      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);
-      g_io_channel_unref (channel);
+      if (client->priv->monitor != NULL)
+        {
+          udev_monitor_enable_receiving (client->priv->monitor);
+          channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor));
+          client->priv->watch_source = g_io_create_watch (channel, G_IO_IN);
+          g_io_channel_unref (channel);
+          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)
@@ -274,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),
@@ -300,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().
  */
@@ -321,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,
@@ -374,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,
@@ -406,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,
@@ -442,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,
@@ -474,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,
@@ -500,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;
+}
+