kernel-device-udev: keep track of the client object
Instead of creating new clients internally whenever we need them, just make sure each MMKernelDeviceUdev object keeps a full reference to the GUdevClient that generated all GUdevDevices.
This commit is contained in:
@@ -31,6 +31,7 @@ G_DEFINE_TYPE_EXTENDED (MMKernelDeviceUdev, mm_kernel_device_udev, MM_TYPE_KERN
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
PROP_UDEV_CLIENT,
|
||||||
PROP_UDEV_DEVICE,
|
PROP_UDEV_DEVICE,
|
||||||
PROP_PROPERTIES,
|
PROP_PROPERTIES,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
@@ -39,6 +40,7 @@ enum {
|
|||||||
static GParamSpec *properties[PROP_LAST];
|
static GParamSpec *properties[PROP_LAST];
|
||||||
|
|
||||||
struct _MMKernelDeviceUdevPrivate {
|
struct _MMKernelDeviceUdevPrivate {
|
||||||
|
GUdevClient *client;
|
||||||
GUdevDevice *device;
|
GUdevDevice *device;
|
||||||
|
|
||||||
GUdevDevice *interface;
|
GUdevDevice *interface;
|
||||||
@@ -565,7 +567,8 @@ kernel_device_get_attribute (MMKernelDevice *_self,
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
MMKernelDevice *
|
MMKernelDevice *
|
||||||
mm_kernel_device_udev_new (GUdevDevice *udev_device)
|
mm_kernel_device_udev_new (GUdevClient *udev_client,
|
||||||
|
GUdevDevice *udev_device)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
MMKernelDevice *self;
|
MMKernelDevice *self;
|
||||||
@@ -574,6 +577,7 @@ mm_kernel_device_udev_new (GUdevDevice *udev_device)
|
|||||||
self = MM_KERNEL_DEVICE (g_initable_new (MM_TYPE_KERNEL_DEVICE_UDEV,
|
self = MM_KERNEL_DEVICE (g_initable_new (MM_TYPE_KERNEL_DEVICE_UDEV,
|
||||||
NULL,
|
NULL,
|
||||||
&error,
|
&error,
|
||||||
|
"udev-client", udev_client,
|
||||||
"udev-device", udev_device,
|
"udev-device", udev_device,
|
||||||
NULL));
|
NULL));
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
@@ -583,13 +587,15 @@ mm_kernel_device_udev_new (GUdevDevice *udev_device)
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
MMKernelDevice *
|
MMKernelDevice *
|
||||||
mm_kernel_device_udev_new_from_properties (MMKernelEventProperties *props,
|
mm_kernel_device_udev_new_from_properties (GUdevClient *udev_client,
|
||||||
|
MMKernelEventProperties *props,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
return MM_KERNEL_DEVICE (g_initable_new (MM_TYPE_KERNEL_DEVICE_UDEV,
|
return MM_KERNEL_DEVICE (g_initable_new (MM_TYPE_KERNEL_DEVICE_UDEV,
|
||||||
NULL,
|
NULL,
|
||||||
error,
|
error,
|
||||||
"properties", props,
|
"udev-client", udev_client,
|
||||||
|
"properties", props,
|
||||||
NULL));
|
NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,6 +617,10 @@ set_property (GObject *object,
|
|||||||
MMKernelDeviceUdev *self = MM_KERNEL_DEVICE_UDEV (object);
|
MMKernelDeviceUdev *self = MM_KERNEL_DEVICE_UDEV (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case PROP_UDEV_CLIENT:
|
||||||
|
g_assert (!self->priv->client);
|
||||||
|
self->priv->client = g_value_dup_object (value);
|
||||||
|
break;
|
||||||
case PROP_UDEV_DEVICE:
|
case PROP_UDEV_DEVICE:
|
||||||
g_assert (!self->priv->device);
|
g_assert (!self->priv->device);
|
||||||
self->priv->device = g_value_dup_object (value);
|
self->priv->device = g_value_dup_object (value);
|
||||||
@@ -634,6 +644,9 @@ get_property (GObject *object,
|
|||||||
MMKernelDeviceUdev *self = MM_KERNEL_DEVICE_UDEV (object);
|
MMKernelDeviceUdev *self = MM_KERNEL_DEVICE_UDEV (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case PROP_UDEV_CLIENT:
|
||||||
|
g_value_set_object (value, self->priv->client);
|
||||||
|
break;
|
||||||
case PROP_UDEV_DEVICE:
|
case PROP_UDEV_DEVICE:
|
||||||
g_value_set_object (value, self->priv->device);
|
g_value_set_object (value, self->priv->device);
|
||||||
break;
|
break;
|
||||||
@@ -655,6 +668,12 @@ initable_init (GInitable *initable,
|
|||||||
const gchar *subsystem;
|
const gchar *subsystem;
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
|
|
||||||
|
if (!self->priv->client) {
|
||||||
|
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||||
|
"missing client in kernel device");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* When created from a GUdevDevice, we're done */
|
/* When created from a GUdevDevice, we're done */
|
||||||
if (self->priv->device) {
|
if (self->priv->device) {
|
||||||
preload_contents (self);
|
preload_contents (self);
|
||||||
@@ -684,23 +703,15 @@ initable_init (GInitable *initable,
|
|||||||
|
|
||||||
/* On remove events, we don't look for the GUdevDevice */
|
/* On remove events, we don't look for the GUdevDevice */
|
||||||
if (g_strcmp0 (mm_kernel_event_properties_get_action (self->priv->properties), "remove")) {
|
if (g_strcmp0 (mm_kernel_event_properties_get_action (self->priv->properties), "remove")) {
|
||||||
GUdevClient *client;
|
g_assert (!self->priv->device);
|
||||||
GUdevDevice *device;
|
self->priv->device = g_udev_client_query_by_subsystem_and_name (self->priv->client, subsystem, name);
|
||||||
|
if (!self->priv->device) {
|
||||||
client = g_udev_client_new (NULL);
|
|
||||||
device = g_udev_client_query_by_subsystem_and_name (client, subsystem, name);
|
|
||||||
if (!device) {
|
|
||||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||||
"device %s/%s not found",
|
"device %s/%s not found",
|
||||||
subsystem,
|
subsystem,
|
||||||
name);
|
name);
|
||||||
g_object_unref (client);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store device */
|
|
||||||
self->priv->device = device;
|
|
||||||
g_object_unref (client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->priv->device)
|
if (self->priv->device)
|
||||||
@@ -717,6 +728,7 @@ dispose (GObject *object)
|
|||||||
g_clear_object (&self->priv->physdev);
|
g_clear_object (&self->priv->physdev);
|
||||||
g_clear_object (&self->priv->interface);
|
g_clear_object (&self->priv->interface);
|
||||||
g_clear_object (&self->priv->device);
|
g_clear_object (&self->priv->device);
|
||||||
|
g_clear_object (&self->priv->client);
|
||||||
g_clear_object (&self->priv->properties);
|
g_clear_object (&self->priv->properties);
|
||||||
|
|
||||||
G_OBJECT_CLASS (mm_kernel_device_udev_parent_class)->dispose (object);
|
G_OBJECT_CLASS (mm_kernel_device_udev_parent_class)->dispose (object);
|
||||||
@@ -774,6 +786,14 @@ mm_kernel_device_udev_class_init (MMKernelDeviceUdevClass *klass)
|
|||||||
G_PARAM_READWRITE);
|
G_PARAM_READWRITE);
|
||||||
g_object_class_install_property (object_class, PROP_UDEV_DEVICE, properties[PROP_UDEV_DEVICE]);
|
g_object_class_install_property (object_class, PROP_UDEV_DEVICE, properties[PROP_UDEV_DEVICE]);
|
||||||
|
|
||||||
|
properties[PROP_UDEV_CLIENT] =
|
||||||
|
g_param_spec_object ("udev-client",
|
||||||
|
"udev client",
|
||||||
|
"GUdev client",
|
||||||
|
G_UDEV_TYPE_CLIENT,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
g_object_class_install_property (object_class, PROP_UDEV_CLIENT, properties[PROP_UDEV_CLIENT]);
|
||||||
|
|
||||||
properties[PROP_PROPERTIES] =
|
properties[PROP_PROPERTIES] =
|
||||||
g_param_spec_object ("properties",
|
g_param_spec_object ("properties",
|
||||||
"Properties",
|
"Properties",
|
||||||
|
@@ -48,8 +48,10 @@ struct _MMKernelDeviceUdevClass {
|
|||||||
GType mm_kernel_device_udev_get_type (void);
|
GType mm_kernel_device_udev_get_type (void);
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMKernelDeviceUdev, g_object_unref)
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMKernelDeviceUdev, g_object_unref)
|
||||||
|
|
||||||
MMKernelDevice *mm_kernel_device_udev_new (GUdevDevice *udev_device);
|
MMKernelDevice *mm_kernel_device_udev_new (GUdevClient *udev_client,
|
||||||
MMKernelDevice *mm_kernel_device_udev_new_from_properties (MMKernelEventProperties *properties,
|
GUdevDevice *udev_device);
|
||||||
|
MMKernelDevice *mm_kernel_device_udev_new_from_properties (GUdevClient *udev_client,
|
||||||
|
MMKernelEventProperties *properties,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
#endif /* MM_KERNEL_DEVICE_UDEV_H */
|
#endif /* MM_KERNEL_DEVICE_UDEV_H */
|
||||||
|
@@ -407,7 +407,7 @@ handle_kernel_event (MMBaseManager *self,
|
|||||||
g_autoptr(MMKernelDevice) kernel_device = NULL;
|
g_autoptr(MMKernelDevice) kernel_device = NULL;
|
||||||
#if defined WITH_UDEV
|
#if defined WITH_UDEV
|
||||||
if (!mm_context_get_test_no_udev ())
|
if (!mm_context_get_test_no_udev ())
|
||||||
kernel_device = mm_kernel_device_udev_new_from_properties (properties, error);
|
kernel_device = mm_kernel_device_udev_new_from_properties (self->priv->udev, properties, error);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
kernel_device = mm_kernel_device_generic_new (properties, error);
|
kernel_device = mm_kernel_device_generic_new (properties, error);
|
||||||
@@ -436,7 +436,7 @@ handle_uevent (MMBaseManager *self,
|
|||||||
if (g_str_equal (action, "add") || g_str_equal (action, "move") || g_str_equal (action, "change")) {
|
if (g_str_equal (action, "add") || g_str_equal (action, "move") || g_str_equal (action, "change")) {
|
||||||
g_autoptr(MMKernelDevice) kernel_device = NULL;
|
g_autoptr(MMKernelDevice) kernel_device = NULL;
|
||||||
|
|
||||||
kernel_device = mm_kernel_device_udev_new (device);
|
kernel_device = mm_kernel_device_udev_new (self->priv->udev, device);
|
||||||
device_added (self, kernel_device, TRUE, FALSE);
|
device_added (self, kernel_device, TRUE, FALSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -458,7 +458,7 @@ start_device_added_idle (StartDeviceAdded *ctx)
|
|||||||
{
|
{
|
||||||
MMKernelDevice *kernel_device;
|
MMKernelDevice *kernel_device;
|
||||||
|
|
||||||
kernel_device = mm_kernel_device_udev_new (ctx->device);
|
kernel_device = mm_kernel_device_udev_new (ctx->self->priv->udev, ctx->device);
|
||||||
device_added (ctx->self, kernel_device, FALSE, ctx->manual_scan);
|
device_added (ctx->self, kernel_device, FALSE, ctx->manual_scan);
|
||||||
g_object_unref (kernel_device);
|
g_object_unref (kernel_device);
|
||||||
|
|
||||||
@@ -1426,13 +1426,12 @@ initable_init (GInitable *initable,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
#if defined WITH_UDEV
|
#if defined WITH_UDEV
|
||||||
if (!mm_context_get_test_no_udev ()) {
|
/* Create udev client based on the subsystems requested by the plugins */
|
||||||
/* Create udev client based on the subsystems requested by the plugins */
|
self->priv->udev = g_udev_client_new (mm_plugin_manager_get_subsystems (self->priv->plugin_manager));
|
||||||
self->priv->udev = g_udev_client_new (mm_plugin_manager_get_subsystems (self->priv->plugin_manager));
|
|
||||||
/* If autoscan enabled, list for udev events */
|
/* If autoscan enabled, list for udev events */
|
||||||
if (self->priv->auto_scan)
|
if (!mm_context_get_test_no_udev () && self->priv->auto_scan)
|
||||||
g_signal_connect_swapped (self->priv->udev, "uevent", G_CALLBACK (handle_uevent), initable);
|
g_signal_connect_swapped (self->priv->udev, "uevent", G_CALLBACK (handle_uevent), initable);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Export the manager interface */
|
/* Export the manager interface */
|
||||||
|
Reference in New Issue
Block a user