backend: Use a GHashTable for device monitors

The array code has been tricky to maintain and leaky. Let's just use a
GHashTable to simplify our lives.
This commit is contained in:
Jasper St. Pierre 2014-12-29 18:57:09 -08:00
parent d9985cd9bc
commit b9fb4a5887
3 changed files with 22 additions and 29 deletions

View File

@ -49,8 +49,7 @@ struct _MetaBackend
{ {
GObject parent; GObject parent;
MetaIdleMonitor *device_monitors[256]; GHashTable *device_monitors;
int device_id_max;
}; };
struct _MetaBackendClass struct _MetaBackendClass

View File

@ -34,6 +34,8 @@
#include "backends/native/meta-backend-native.h" #include "backends/native/meta-backend-native.h"
#endif #endif
#include "backends/meta-idle-monitor-private.h"
static MetaBackend *_backend; static MetaBackend *_backend;
/** /**
@ -65,15 +67,10 @@ meta_backend_finalize (GObject *object)
{ {
MetaBackend *backend = META_BACKEND (object); MetaBackend *backend = META_BACKEND (object);
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
int i;
g_clear_object (&priv->monitor_manager); g_clear_object (&priv->monitor_manager);
for (i = 0; i <= backend->device_id_max; i++) g_hash_table_destroy (backend->device_monitors);
{
if (backend->device_monitors[i])
g_object_unref (backend->device_monitors[i]);
}
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object); G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
} }
@ -108,27 +105,19 @@ static void
create_device_monitor (MetaBackend *backend, create_device_monitor (MetaBackend *backend,
int device_id) int device_id)
{ {
g_assert (backend->device_monitors[device_id] == NULL); MetaIdleMonitor *idle_monitor;
backend->device_monitors[device_id] = meta_backend_create_idle_monitor (backend, device_id); g_assert (g_hash_table_lookup (backend->device_monitors, &device_id) == NULL);
backend->device_id_max = MAX (backend->device_id_max, device_id);
idle_monitor = meta_backend_create_idle_monitor (backend, device_id);
g_hash_table_insert (backend->device_monitors, &idle_monitor->device_id, idle_monitor);
} }
static void static void
destroy_device_monitor (MetaBackend *backend, destroy_device_monitor (MetaBackend *backend,
int device_id) int device_id)
{ {
g_clear_object (&backend->device_monitors[device_id]); g_hash_table_remove (backend->device_monitors, &device_id);
if (device_id == backend->device_id_max)
{
/* Reset the max device ID */
int i, new_max = 0;
for (i = 0; i < backend->device_id_max; i++)
if (backend->device_monitors[i] != NULL)
new_max = i;
backend->device_id_max = new_max;
}
} }
static void static void
@ -170,6 +159,9 @@ meta_backend_real_post_init (MetaBackend *backend)
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend); priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
backend->device_monitors = g_hash_table_new_full (g_int_hash, g_int_equal,
NULL, (GDestroyNotify) g_object_unref);
{ {
ClutterDeviceManager *manager; ClutterDeviceManager *manager;
GSList *devices, *l; GSList *devices, *l;
@ -281,9 +273,7 @@ MetaIdleMonitor *
meta_backend_get_idle_monitor (MetaBackend *backend, meta_backend_get_idle_monitor (MetaBackend *backend,
int device_id) int device_id)
{ {
g_return_val_if_fail (device_id >= 0 && device_id < 256, NULL); return g_hash_table_lookup (backend->device_monitors, &device_id);
return backend->device_monitors[device_id];
} }
/** /**

View File

@ -79,11 +79,15 @@ static void
handle_alarm_notify (MetaBackend *backend, handle_alarm_notify (MetaBackend *backend,
XEvent *event) XEvent *event)
{ {
int i; GHashTableIter iter;
gpointer value;
for (i = 0; i <= backend->device_id_max; i++) g_hash_table_iter_init (&iter, backend->device_monitors);
if (backend->device_monitors[i]) while (g_hash_table_iter_next (&iter, NULL, &value))
meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*) event); {
MetaIdleMonitor *device_monitor = META_IDLE_MONITOR (value);
meta_idle_monitor_xsync_handle_xevent (device_monitor, (XSyncAlarmNotifyEvent*) event);
}
} }
static void static void