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:
Aleksander Morgado
2021-02-12 11:02:14 +01:00
parent 1b35d74c15
commit b8e076f9c4
3 changed files with 47 additions and 26 deletions

View File

@@ -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",

View File

@@ -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 */

View File

@@ -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 */