diff options
author | Georges Basile Stavracas Neto <georges.stavracas@gmail.com> | 2022-10-13 22:22:52 -0300 |
---|---|---|
committer | Georges Basile Stavracas Neto <georges.stavracas@gmail.com> | 2022-10-17 23:37:13 -0300 |
commit | 16b9337e3ff119923ab27375745c4bdfa5425e2f (patch) | |
tree | 90d8459df3c3b5b601f3e29f6642d9fa5b5b2afd | |
parent | 791d443c54fc9ee37c8a04a977feb741a2f5218f (diff) | |
download | gnome-calendar-16b9337e3ff119923ab27375745c4bdfa5425e2f.tar.gz |
calendar-monitor: Move events hash table to shared section
We'll start accessing the hash table from multiple threads, so
it must be in the shared section of the structure, and it must
be encapsulated by locking.
-rw-r--r-- | src/core/gcal-calendar-monitor.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/src/core/gcal-calendar-monitor.c b/src/core/gcal-calendar-monitor.c index 8c558e45..0377dd0a 100644 --- a/src/core/gcal-calendar-monitor.c +++ b/src/core/gcal-calendar-monitor.c @@ -55,8 +55,6 @@ struct _GcalCalendarMonitor GMainContext *thread_context; GMainContext *main_context; - GHashTable *events; /* gchar* -> GcalEvent* */ - GAsyncQueue *messages; GcalCalendar *calendar; gboolean complete; @@ -77,6 +75,7 @@ struct _GcalCalendarMonitor */ struct { GRWLock lock; + GHashTable *events; /* gchar* -> GcalEvent* */ GcalRange *range; gchar *filter; } shared; @@ -830,12 +829,15 @@ static void remove_events_outside_range (GcalCalendarMonitor *self, GcalRange *range) { + g_autoptr (GRWLockWriterLocker) writer_locker = NULL; GHashTableIter iter; GcalEvent *event; GCAL_TRACE_MSG ("Removing events outside range from monitor"); - g_hash_table_iter_init (&iter, self->events); + writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock); + + g_hash_table_iter_init (&iter, self->shared.events); while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &event)) { g_object_ref (event); @@ -850,12 +852,15 @@ remove_events_outside_range (GcalCalendarMonitor *self, static void remove_all_events (GcalCalendarMonitor *self) { + g_autoptr (GRWLockWriterLocker) writer_locker = NULL; GHashTableIter iter; GcalEvent *event; GCAL_TRACE_MSG ("Removing all events from view"); - g_hash_table_iter_init (&iter, self->events); + writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock); + + g_hash_table_iter_init (&iter, self->shared.events); while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &event)) { g_hash_table_iter_remove (&iter); @@ -884,6 +889,7 @@ set_complete (GcalCalendarMonitor *self, static gboolean add_event_to_timeline_in_idle_cb (gpointer user_data) { + g_autoptr (GRWLockWriterLocker) writer_locker = NULL; GcalCalendarMonitor *self; GcalEvent *event; IdleData *idle_data; @@ -897,7 +903,9 @@ add_event_to_timeline_in_idle_cb (gpointer user_data) g_assert (idle_data->event_id == NULL); event_id = gcal_event_get_uid (event); - if (g_hash_table_insert (self->events, g_strdup (event_id), g_object_ref (event))) + + writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock); + if (g_hash_table_insert (self->shared.events, g_strdup (event_id), g_object_ref (event))) g_signal_emit (self, signals[EVENT_ADDED], 0, event); GCAL_RETURN (G_SOURCE_REMOVE); @@ -906,6 +914,7 @@ add_event_to_timeline_in_idle_cb (gpointer user_data) static gboolean update_event_in_idle_cb (gpointer user_data) { + g_autoptr (GRWLockWriterLocker) writer_locker = NULL; GcalCalendarMonitor *self; GcalEvent *old_event; GcalEvent *event; @@ -920,10 +929,12 @@ update_event_in_idle_cb (gpointer user_data) g_assert (idle_data->event_id == NULL); event_id = gcal_event_get_uid (event); - old_event = g_hash_table_lookup (self->events, event_id); + + writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock); + old_event = g_hash_table_lookup (self->shared.events, event_id); if (old_event) { - g_hash_table_insert (self->events, g_strdup (event_id), g_object_ref (event)); + g_hash_table_insert (self->shared.events, g_strdup (event_id), g_object_ref (event)); g_signal_emit (self, signals[EVENT_UPDATED], 0, old_event, event); } @@ -933,6 +944,7 @@ update_event_in_idle_cb (gpointer user_data) static gboolean remove_event_from_timeline_in_idle_cb (gpointer user_data) { + g_autoptr (GRWLockWriterLocker) writer_locker = NULL; g_autoptr (GcalEvent) event = NULL; GcalCalendarMonitor *self; IdleData *idle_data; @@ -945,14 +957,15 @@ remove_event_from_timeline_in_idle_cb (gpointer user_data) g_assert (idle_data->event == NULL); event_id = idle_data->event_id; - event = g_hash_table_lookup (self->events, event_id); + writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock); + event = g_hash_table_lookup (self->shared.events, event_id); if (event) { /* Keep the event alive until the signal is emitted */ g_object_ref (event); - g_hash_table_remove (self->events, event_id); + g_hash_table_remove (self->shared.events, event_id); g_signal_emit (self, signals[EVENT_REMOVED], 0, event); } @@ -1010,10 +1023,10 @@ gcal_calendar_monitor_finalize (GObject *object) remove_all_events (self); g_clear_object (&self->calendar); - g_clear_pointer (&self->events, g_hash_table_destroy); g_clear_pointer (&self->thread_context, g_main_context_unref); g_clear_pointer (&self->main_context, g_main_context_unref); g_clear_pointer (&self->messages, g_async_queue_unref); + g_clear_pointer (&self->shared.events, g_hash_table_destroy); g_clear_pointer (&self->shared.filter, g_free); g_clear_pointer (&self->shared.range, gcal_range_unref); @@ -1121,7 +1134,7 @@ gcal_calendar_monitor_class_init (GcalCalendarMonitorClass *klass) static void gcal_calendar_monitor_init (GcalCalendarMonitor *self) { - self->events = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + self->shared.events = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); self->thread_context = g_main_context_new (); self->main_context = g_main_context_ref_thread_default (); self->messages = g_async_queue_new (); @@ -1200,7 +1213,9 @@ gcal_calendar_monitor_get_cached_event (GcalCalendarMonitor *self, g_return_val_if_fail (GCAL_IS_CALENDAR_MONITOR (self), NULL); g_return_val_if_fail (event_id, NULL); - event = g_hash_table_lookup (self->events, event_id); + g_rw_lock_reader_lock (&self->shared.lock); + event = g_hash_table_lookup (self->shared.events, event_id); + g_rw_lock_reader_unlock (&self->shared.lock); return event ? g_object_ref (event) : NULL; } |