[mutter/wip/carlosg/input-thread: 57/87] backends/native: Protect MetaBarrierManagerNative
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/carlosg/input-thread: 57/87] backends/native: Protect MetaBarrierManagerNative
- Date: Fri, 27 Nov 2020 15:14:56 +0000 (UTC)
commit e76a7f43e02d360b624425816181a28144b61faf
Author: Carlos Garnacho <carlosg gnome org>
Date: Tue Aug 11 20:21:08 2020 +0200
backends/native: Protect MetaBarrierManagerNative
While barriers will be added from the main thread, the native barrier
manager will sit close to the MetaSeatImpl in its own thread. Add the
necessary locking so that we can pass MetaBarrierImplNative from the
UI thread to the input thread, and ensure the MetaBarrier signals are
still emitted in the UI thread.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
src/backends/native/meta-barrier-native.c | 64 +++++++++++++++++++++++++++----
1 file changed, 57 insertions(+), 7 deletions(-)
---
diff --git a/src/backends/native/meta-barrier-native.c b/src/backends/native/meta-barrier-native.c
index bdb006fb13..8db73ee068 100644
--- a/src/backends/native/meta-barrier-native.c
+++ b/src/backends/native/meta-barrier-native.c
@@ -43,6 +43,7 @@
struct _MetaBarrierManagerNative
{
GHashTable *barriers;
+ GMutex mutex;
};
typedef enum
@@ -77,6 +78,7 @@ struct _MetaBarrierImplNative
int trigger_serial;
guint32 last_event_time;
MetaBarrierDirection blocked_dir;
+ GMainContext *main_context;
};
G_DEFINE_TYPE (MetaBarrierImplNative,
@@ -340,6 +342,49 @@ typedef struct _MetaBarrierEventData
float dy;
} MetaBarrierEventData;
+typedef struct
+{
+ MetaBarrierEvent *event;
+ MetaBarrier *barrier;
+ MetaBarrierState state;
+} MetaBarrierIdleData;
+
+static gboolean
+emit_event_idle (MetaBarrierIdleData *idle_data)
+{
+ if (idle_data->state == META_BARRIER_STATE_HELD)
+ _meta_barrier_emit_hit_signal (idle_data->barrier, idle_data->event);
+ else
+ _meta_barrier_emit_left_signal (idle_data->barrier, idle_data->event);
+
+ meta_barrier_event_unref (idle_data->event);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+queue_event (MetaBarrierImplNative *self,
+ MetaBarrierEvent *event)
+{
+ MetaBarrierIdleData *idle_data;
+ GSource *source;
+
+ idle_data = g_new0 (MetaBarrierIdleData, 1);
+ idle_data->state = self->state;
+ idle_data->barrier = self->barrier;
+ idle_data->event = event;
+
+ source = g_idle_source_new ();
+ g_source_set_priority (source, G_PRIORITY_HIGH);
+ g_source_set_callback (source,
+ (GSourceFunc) emit_event_idle,
+ idle_data,
+ g_free);
+
+ g_source_attach (source, self->main_context);
+ g_source_unref (source);
+}
+
static void
emit_barrier_event (MetaBarrierImplNative *self,
guint32 time,
@@ -350,7 +395,6 @@ emit_barrier_event (MetaBarrierImplNative *self,
float dx,
float dy)
{
- MetaBarrier *barrier = self->barrier;
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
MetaBarrierState old_state = self->state;
@@ -389,12 +433,7 @@ emit_barrier_event (MetaBarrierImplNative *self,
self->last_event_time = time;
- if (self->state == META_BARRIER_STATE_HELD)
- _meta_barrier_emit_hit_signal (barrier, event);
- else
- _meta_barrier_emit_left_signal (barrier, event);
-
- meta_barrier_event_unref (event);
+ queue_event (self, event);
}
static void
@@ -479,6 +518,8 @@ meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
if (!clutter_input_device_get_coords (device, NULL, &prev_pos))
return;
+ g_mutex_lock (&manager->mutex);
+
prev_x = prev_pos.x;
prev_y = prev_pos.y;
@@ -523,6 +564,8 @@ meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
g_hash_table_foreach (manager->barriers,
maybe_emit_barrier_event,
&barrier_event_data);
+
+ g_mutex_unlock (&manager->mutex);
}
static gboolean
@@ -549,7 +592,10 @@ _meta_barrier_impl_native_destroy (MetaBarrierImpl *impl)
{
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
+ g_mutex_lock (&self->manager->mutex);
g_hash_table_remove (self->manager->barriers, self);
+ g_mutex_unlock (&self->manager->mutex);
+ g_main_context_unref (self->main_context);
self->is_active = FALSE;
}
@@ -565,10 +611,13 @@ meta_barrier_impl_native_new (MetaBarrier *barrier)
self->barrier = barrier;
self->is_active = TRUE;
+ self->main_context = g_main_context_ref_thread_default ();
manager = meta_seat_native_get_barrier_manager (META_SEAT_NATIVE (seat));
self->manager = manager;
+ g_mutex_lock (&manager->mutex);
g_hash_table_add (manager->barriers, self);
+ g_mutex_unlock (&manager->mutex);
return META_BARRIER_IMPL (self);
}
@@ -596,6 +645,7 @@ meta_barrier_manager_native_new (void)
manager = g_new0 (MetaBarrierManagerNative, 1);
manager->barriers = g_hash_table_new (NULL, NULL);
+ g_mutex_init (&manager->mutex);
return manager;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]