X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=extras%2Fgudev%2Fgudevclient.c;h=97b951adcd421e559c4a2d7b3b822eb95dd01f1d;hp=fa31f70bf5b278381892e62414ada57c8ce12f98;hb=079de714754b1e058f57220281e7f901d4c826d6;hpb=214a6c791cbc0c1a190c430eb37056087e661344 diff --git a/extras/gudev/gudevclient.c b/extras/gudev/gudevclient.c index fa31f70bf..97b951adc 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 + * Copyright (C) 2008-2010 David Zeuthen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -47,19 +47,20 @@ * 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 + * thread-default main loop + * 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 + * thread-default main loop + * 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; +} +