mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
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. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403
This commit is contained in:
parent
6496cd7c55
commit
d55b44df50
@ -43,6 +43,7 @@
|
|||||||
struct _MetaBarrierManagerNative
|
struct _MetaBarrierManagerNative
|
||||||
{
|
{
|
||||||
GHashTable *barriers;
|
GHashTable *barriers;
|
||||||
|
GMutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -77,6 +78,7 @@ struct _MetaBarrierImplNative
|
|||||||
int trigger_serial;
|
int trigger_serial;
|
||||||
guint32 last_event_time;
|
guint32 last_event_time;
|
||||||
MetaBarrierDirection blocked_dir;
|
MetaBarrierDirection blocked_dir;
|
||||||
|
GMainContext *context;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaBarrierImplNative,
|
G_DEFINE_TYPE (MetaBarrierImplNative,
|
||||||
@ -340,6 +342,48 @@ typedef struct _MetaBarrierEventData
|
|||||||
float dy;
|
float dy;
|
||||||
} MetaBarrierEventData;
|
} 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
|
||||||
|
emit_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->context);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_barrier_event (MetaBarrierImplNative *self,
|
emit_barrier_event (MetaBarrierImplNative *self,
|
||||||
guint32 time,
|
guint32 time,
|
||||||
@ -350,7 +394,6 @@ emit_barrier_event (MetaBarrierImplNative *self,
|
|||||||
float dx,
|
float dx,
|
||||||
float dy)
|
float dy)
|
||||||
{
|
{
|
||||||
MetaBarrier *barrier = self->barrier;
|
|
||||||
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
||||||
MetaBarrierState old_state = self->state;
|
MetaBarrierState old_state = self->state;
|
||||||
|
|
||||||
@ -389,12 +432,7 @@ emit_barrier_event (MetaBarrierImplNative *self,
|
|||||||
|
|
||||||
self->last_event_time = time;
|
self->last_event_time = time;
|
||||||
|
|
||||||
if (self->state == META_BARRIER_STATE_HELD)
|
emit_event (self, event);
|
||||||
_meta_barrier_emit_hit_signal (barrier, event);
|
|
||||||
else
|
|
||||||
_meta_barrier_emit_left_signal (barrier, event);
|
|
||||||
|
|
||||||
meta_barrier_event_unref (event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -479,6 +517,8 @@ meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
|
|||||||
if (!clutter_input_device_get_coords (device, NULL, &prev_pos))
|
if (!clutter_input_device_get_coords (device, NULL, &prev_pos))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
g_mutex_lock (&manager->mutex);
|
||||||
|
|
||||||
prev_x = prev_pos.x;
|
prev_x = prev_pos.x;
|
||||||
prev_y = prev_pos.y;
|
prev_y = prev_pos.y;
|
||||||
|
|
||||||
@ -523,6 +563,8 @@ meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
|
|||||||
g_hash_table_foreach (manager->barriers,
|
g_hash_table_foreach (manager->barriers,
|
||||||
maybe_emit_barrier_event,
|
maybe_emit_barrier_event,
|
||||||
&barrier_event_data);
|
&barrier_event_data);
|
||||||
|
|
||||||
|
g_mutex_unlock (&manager->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -549,7 +591,10 @@ _meta_barrier_impl_native_destroy (MetaBarrierImpl *impl)
|
|||||||
{
|
{
|
||||||
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
||||||
|
|
||||||
|
g_mutex_lock (&self->manager->mutex);
|
||||||
g_hash_table_remove (self->manager->barriers, self);
|
g_hash_table_remove (self->manager->barriers, self);
|
||||||
|
g_mutex_unlock (&self->manager->mutex);
|
||||||
|
g_main_context_unref (self->context);
|
||||||
self->is_active = FALSE;
|
self->is_active = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,10 +610,13 @@ meta_barrier_impl_native_new (MetaBarrier *barrier)
|
|||||||
|
|
||||||
self->barrier = barrier;
|
self->barrier = barrier;
|
||||||
self->is_active = TRUE;
|
self->is_active = TRUE;
|
||||||
|
self->context = g_main_context_ref_thread_default ();
|
||||||
|
|
||||||
manager = meta_seat_native_get_barrier_manager (META_SEAT_NATIVE (seat));
|
manager = meta_seat_native_get_barrier_manager (META_SEAT_NATIVE (seat));
|
||||||
self->manager = manager;
|
self->manager = manager;
|
||||||
|
g_mutex_lock (&manager->mutex);
|
||||||
g_hash_table_add (manager->barriers, self);
|
g_hash_table_add (manager->barriers, self);
|
||||||
|
g_mutex_unlock (&manager->mutex);
|
||||||
|
|
||||||
return META_BARRIER_IMPL (self);
|
return META_BARRIER_IMPL (self);
|
||||||
}
|
}
|
||||||
@ -596,6 +644,7 @@ meta_barrier_manager_native_new (void)
|
|||||||
manager = g_new0 (MetaBarrierManagerNative, 1);
|
manager = g_new0 (MetaBarrierManagerNative, 1);
|
||||||
|
|
||||||
manager->barriers = g_hash_table_new (NULL, NULL);
|
manager->barriers = g_hash_table_new (NULL, NULL);
|
||||||
|
g_mutex_init (&manager->mutex);
|
||||||
|
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user