calendar-monitor: Operate in batches
Instead of smashing the main thread's mainloop with potentially hundreds or even thousands of idles that add, remove, or update individual events, pass arrays of events around.
This commit is contained in:
+132
-117
@@ -31,8 +31,8 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GcalCalendarMonitor *monitor;
|
GcalCalendarMonitor *monitor;
|
||||||
GcalEvent *event;
|
GPtrArray *events;
|
||||||
gchar *event_id;
|
GPtrArray *event_ids;
|
||||||
gboolean complete;
|
gboolean complete;
|
||||||
} IdleData;
|
} IdleData;
|
||||||
|
|
||||||
@@ -81,9 +81,9 @@ struct _GcalCalendarMonitor
|
|||||||
} shared;
|
} shared;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean add_event_to_timeline_in_idle_cb (gpointer user_data);
|
static gboolean add_events_to_timeline_in_idle_cb (gpointer user_data);
|
||||||
static gboolean update_event_in_idle_cb (gpointer user_data);
|
static gboolean update_events_in_idle_cb (gpointer user_data);
|
||||||
static gboolean remove_event_from_timeline_in_idle_cb (gpointer user_data);
|
static gboolean remove_events_from_timeline_in_idle_cb (gpointer user_data);
|
||||||
static gboolean complete_in_idle_cb (gpointer user_data);
|
static gboolean complete_in_idle_cb (gpointer user_data);
|
||||||
|
|
||||||
G_DEFINE_TYPE (GcalCalendarMonitor, gcal_calendar_monitor, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (GcalCalendarMonitor, gcal_calendar_monitor, G_TYPE_OBJECT)
|
||||||
@@ -183,58 +183,58 @@ static void
|
|||||||
idle_data_free (IdleData *data)
|
idle_data_free (IdleData *data)
|
||||||
{
|
{
|
||||||
g_clear_object (&data->monitor);
|
g_clear_object (&data->monitor);
|
||||||
g_clear_object (&data->event);
|
g_clear_pointer (&data->events, g_ptr_array_unref);
|
||||||
g_clear_pointer (&data->event_id, g_free);
|
g_clear_pointer (&data->event_ids, g_ptr_array_unref);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_event_in_idle (GcalCalendarMonitor *self,
|
add_events_in_idle (GcalCalendarMonitor *self,
|
||||||
GcalEvent *event)
|
GPtrArray *events)
|
||||||
{
|
{
|
||||||
IdleData *idle_data;
|
IdleData *idle_data;
|
||||||
|
|
||||||
idle_data = g_new0 (IdleData, 1);
|
idle_data = g_new0 (IdleData, 1);
|
||||||
idle_data->monitor = g_object_ref (self);
|
idle_data->monitor = g_object_ref (self);
|
||||||
idle_data->event = g_object_ref (event);
|
idle_data->events = g_ptr_array_ref (events);
|
||||||
|
|
||||||
g_main_context_invoke_full (self->main_context,
|
g_main_context_invoke_full (self->main_context,
|
||||||
G_PRIORITY_DEFAULT_IDLE,
|
G_PRIORITY_DEFAULT_IDLE,
|
||||||
add_event_to_timeline_in_idle_cb,
|
add_events_to_timeline_in_idle_cb,
|
||||||
idle_data,
|
idle_data,
|
||||||
(GDestroyNotify) idle_data_free);
|
(GDestroyNotify) idle_data_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_event_in_idle (GcalCalendarMonitor *self,
|
update_events_in_idle (GcalCalendarMonitor *self,
|
||||||
GcalEvent *event)
|
GPtrArray *events)
|
||||||
{
|
{
|
||||||
IdleData *idle_data;
|
IdleData *idle_data;
|
||||||
|
|
||||||
idle_data = g_new0 (IdleData, 1);
|
idle_data = g_new0 (IdleData, 1);
|
||||||
idle_data->monitor = g_object_ref (self);
|
idle_data->monitor = g_object_ref (self);
|
||||||
idle_data->event = g_object_ref (event);
|
idle_data->events = g_ptr_array_ref (events);
|
||||||
|
|
||||||
g_main_context_invoke_full (self->main_context,
|
g_main_context_invoke_full (self->main_context,
|
||||||
G_PRIORITY_DEFAULT_IDLE,
|
G_PRIORITY_DEFAULT_IDLE,
|
||||||
update_event_in_idle_cb,
|
update_events_in_idle_cb,
|
||||||
idle_data,
|
idle_data,
|
||||||
(GDestroyNotify) idle_data_free);
|
(GDestroyNotify) idle_data_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_event_in_idle (GcalCalendarMonitor *self,
|
remove_events_in_idle (GcalCalendarMonitor *self,
|
||||||
const gchar *event_id)
|
GPtrArray *events)
|
||||||
{
|
{
|
||||||
IdleData *idle_data;
|
IdleData *idle_data;
|
||||||
|
|
||||||
idle_data = g_new0 (IdleData, 1);
|
idle_data = g_new0 (IdleData, 1);
|
||||||
idle_data->monitor = g_object_ref (self);
|
idle_data->monitor = g_object_ref (self);
|
||||||
idle_data->event_id = g_strdup (event_id);
|
idle_data->events = g_ptr_array_ref (events);
|
||||||
|
|
||||||
g_main_context_invoke_full (self->main_context,
|
g_main_context_invoke_full (self->main_context,
|
||||||
G_PRIORITY_DEFAULT_IDLE,
|
G_PRIORITY_DEFAULT_IDLE,
|
||||||
remove_event_from_timeline_in_idle_cb,
|
remove_events_from_timeline_in_idle_cb,
|
||||||
idle_data,
|
idle_data,
|
||||||
(GDestroyNotify) idle_data_free);
|
(GDestroyNotify) idle_data_free);
|
||||||
}
|
}
|
||||||
@@ -305,6 +305,7 @@ on_client_view_objects_added_cb (ECalClientView *view,
|
|||||||
GcalCalendarMonitor *self)
|
GcalCalendarMonitor *self)
|
||||||
{
|
{
|
||||||
g_autoptr (GPtrArray) components_to_expand = NULL;
|
g_autoptr (GPtrArray) components_to_expand = NULL;
|
||||||
|
g_autoptr (GPtrArray) events_to_add = NULL;
|
||||||
g_autoptr (GcalRange) range = NULL;
|
g_autoptr (GcalRange) range = NULL;
|
||||||
const GSList *l;
|
const GSList *l;
|
||||||
gint i;
|
gint i;
|
||||||
@@ -315,6 +316,7 @@ on_client_view_objects_added_cb (ECalClientView *view,
|
|||||||
|
|
||||||
maybe_init_event_arrays (self);
|
maybe_init_event_arrays (self);
|
||||||
components_to_expand = g_ptr_array_new ();
|
components_to_expand = g_ptr_array_new ();
|
||||||
|
events_to_add = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
|
|
||||||
for (l = objects; l; l = l->next)
|
for (l = objects; l; l = l->next)
|
||||||
{
|
{
|
||||||
@@ -359,13 +361,12 @@ on_client_view_objects_added_cb (ECalClientView *view,
|
|||||||
if (!self->monitor_thread.populated)
|
if (!self->monitor_thread.populated)
|
||||||
g_ptr_array_add (self->monitor_thread.events_to_add, g_object_ref (event));
|
g_ptr_array_add (self->monitor_thread.events_to_add, g_object_ref (event));
|
||||||
else
|
else
|
||||||
add_event_in_idle (self, event);
|
g_ptr_array_add (events_to_add, g_object_ref (event));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recurrent events */
|
/* Recurrent events */
|
||||||
if (components_to_expand->len > 0)
|
if (components_to_expand->len > 0)
|
||||||
{
|
{
|
||||||
g_autoptr (GPtrArray) expanded_events = NULL;
|
|
||||||
g_autoptr (GDateTime) range_start = NULL;
|
g_autoptr (GDateTime) range_start = NULL;
|
||||||
g_autoptr (GDateTime) range_end = NULL;
|
g_autoptr (GDateTime) range_end = NULL;
|
||||||
ECalClient *client;
|
ECalClient *client;
|
||||||
@@ -381,8 +382,6 @@ on_client_view_objects_added_cb (ECalClientView *view,
|
|||||||
range_start_time = g_date_time_to_unix (range_start);
|
range_start_time = g_date_time_to_unix (range_start);
|
||||||
range_end_time = g_date_time_to_unix (range_end) - 1;
|
range_end_time = g_date_time_to_unix (range_end) - 1;
|
||||||
|
|
||||||
expanded_events = g_ptr_array_new_with_free_func (g_object_unref);
|
|
||||||
|
|
||||||
/* Generate the instances */
|
/* Generate the instances */
|
||||||
for (i = 0; i < components_to_expand->len; i++)
|
for (i = 0; i < components_to_expand->len; i++)
|
||||||
{
|
{
|
||||||
@@ -398,10 +397,14 @@ on_client_view_objects_added_cb (ECalClientView *view,
|
|||||||
icomponent = g_ptr_array_index (components_to_expand, i);
|
icomponent = g_ptr_array_index (components_to_expand, i);
|
||||||
|
|
||||||
recurrences_data.monitor = self;
|
recurrences_data.monitor = self;
|
||||||
recurrences_data.expanded_events = expanded_events;
|
|
||||||
|
if (!self->monitor_thread.populated)
|
||||||
|
recurrences_data.expanded_events = self->monitor_thread.events_to_add;
|
||||||
|
else
|
||||||
|
recurrences_data.expanded_events = events_to_add;
|
||||||
|
|
||||||
#if GCAL_ENABLE_TRACE
|
#if GCAL_ENABLE_TRACE
|
||||||
old_size = expanded_events->len;
|
old_size = recurrences_data.expanded_events->len;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
e_cal_client_generate_instances_for_object_sync (client,
|
e_cal_client_generate_instances_for_object_sync (client,
|
||||||
@@ -419,27 +422,16 @@ on_client_view_objects_added_cb (ECalClientView *view,
|
|||||||
GCAL_TRACE_MSG ("Component %s (%s) added %d instance(s) between %s",
|
GCAL_TRACE_MSG ("Component %s (%s) added %d instance(s) between %s",
|
||||||
i_cal_component_get_summary (icomponent),
|
i_cal_component_get_summary (icomponent),
|
||||||
i_cal_component_get_uid (icomponent),
|
i_cal_component_get_uid (icomponent),
|
||||||
expanded_events->len - old_size,
|
recurrences_data.expanded_events->len - old_size,
|
||||||
range_str);
|
range_str);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process all these instances */
|
|
||||||
for (i = 0; i < expanded_events->len; i++)
|
|
||||||
{
|
|
||||||
GcalEvent *event = g_ptr_array_index (expanded_events, i);
|
|
||||||
|
|
||||||
if (g_cancellable_is_cancelled (self->cancellable))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!self->monitor_thread.populated)
|
|
||||||
g_ptr_array_add (self->monitor_thread.events_to_add, g_object_ref (event));
|
|
||||||
else
|
|
||||||
add_event_in_idle (self, event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (events_to_add->len > 0)
|
||||||
|
add_events_in_idle (self, events_to_add);
|
||||||
|
|
||||||
GCAL_EXIT;
|
GCAL_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,10 +443,10 @@ on_client_view_objects_modified_cb (ECalClientView *view,
|
|||||||
g_autoptr (GRWLockReaderLocker) reader_locker = NULL;
|
g_autoptr (GRWLockReaderLocker) reader_locker = NULL;
|
||||||
g_autoptr (GHashTable) events_to_remove = NULL;
|
g_autoptr (GHashTable) events_to_remove = NULL;
|
||||||
g_autoptr (GPtrArray) components_to_expand = NULL;
|
g_autoptr (GPtrArray) components_to_expand = NULL;
|
||||||
|
g_autoptr (GPtrArray) event_ids_to_remove = NULL;
|
||||||
|
g_autoptr (GPtrArray) events_to_update = NULL;
|
||||||
g_autoptr (GcalRange) range = NULL;
|
g_autoptr (GcalRange) range = NULL;
|
||||||
GHashTableIter iter;
|
|
||||||
const GSList *l;
|
const GSList *l;
|
||||||
const gchar *aux;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
GCAL_ENTRY;
|
||||||
|
|
||||||
@@ -467,6 +459,7 @@ on_client_view_objects_modified_cb (ECalClientView *view,
|
|||||||
reader_locker = g_rw_lock_reader_locker_new (&self->shared.lock);
|
reader_locker = g_rw_lock_reader_locker_new (&self->shared.lock);
|
||||||
components_to_expand = g_ptr_array_new ();
|
components_to_expand = g_ptr_array_new ();
|
||||||
events_to_remove = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
events_to_remove = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
events_to_update = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
range = gcal_range_copy (self->shared.range);
|
range = gcal_range_copy (self->shared.range);
|
||||||
|
|
||||||
for (l = objects; l; l = l->next)
|
for (l = objects; l; l = l->next)
|
||||||
@@ -506,6 +499,9 @@ on_client_view_objects_modified_cb (ECalClientView *view,
|
|||||||
|
|
||||||
if (!e_cal_component_id_get_rid (component_id))
|
if (!e_cal_component_id_get_rid (component_id))
|
||||||
{
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
const gchar *aux;
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, self->shared.events);
|
g_hash_table_iter_init (&iter, self->shared.events);
|
||||||
while (g_hash_table_iter_next (&iter, (gpointer*) &aux, NULL))
|
while (g_hash_table_iter_next (&iter, (gpointer*) &aux, NULL))
|
||||||
{
|
{
|
||||||
@@ -537,13 +533,14 @@ on_client_view_objects_modified_cb (ECalClientView *view,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_event_in_idle (self, event);
|
g_ptr_array_add (events_to_update, g_steal_pointer (&event));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recurrent events */
|
/* Recurrent events */
|
||||||
if (components_to_expand->len > 0)
|
if (components_to_expand->len > 0)
|
||||||
{
|
{
|
||||||
g_autoptr (GPtrArray) expanded_events = NULL;
|
g_autoptr (GPtrArray) expanded_events = NULL;
|
||||||
|
g_autoptr (GPtrArray) events_to_add = NULL;
|
||||||
g_autoptr (GDateTime) range_start = NULL;
|
g_autoptr (GDateTime) range_start = NULL;
|
||||||
g_autoptr (GDateTime) range_end = NULL;
|
g_autoptr (GDateTime) range_end = NULL;
|
||||||
ECalClient *client;
|
ECalClient *client;
|
||||||
@@ -560,6 +557,7 @@ on_client_view_objects_modified_cb (ECalClientView *view,
|
|||||||
range_end_time = g_date_time_to_unix (range_end) - 1;
|
range_end_time = g_date_time_to_unix (range_end) - 1;
|
||||||
|
|
||||||
expanded_events = g_ptr_array_new_with_free_func (g_object_unref);
|
expanded_events = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
|
events_to_add = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
|
|
||||||
/* Generate the instances */
|
/* Generate the instances */
|
||||||
for (guint i = 0; i < components_to_expand->len; i++)
|
for (guint i = 0; i < components_to_expand->len; i++)
|
||||||
@@ -614,20 +612,26 @@ on_client_view_objects_modified_cb (ECalClientView *view,
|
|||||||
old_event = g_hash_table_lookup (self->shared.events, gcal_event_get_uid (event));
|
old_event = g_hash_table_lookup (self->shared.events, gcal_event_get_uid (event));
|
||||||
if (old_event)
|
if (old_event)
|
||||||
{
|
{
|
||||||
update_event_in_idle (self, event);
|
|
||||||
g_hash_table_remove (events_to_remove, gcal_event_get_uid (event));
|
g_hash_table_remove (events_to_remove, gcal_event_get_uid (event));
|
||||||
|
g_ptr_array_add (events_to_update, g_steal_pointer (&event));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add_event_in_idle (self, event);
|
g_ptr_array_add (events_to_add, g_steal_pointer (&event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (events_to_add->len > 0)
|
||||||
|
add_events_in_idle (self, events_to_add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (events_to_update->len > 0)
|
||||||
|
update_events_in_idle (self, events_to_update);
|
||||||
|
|
||||||
/* Now remove lingering events */
|
/* Now remove lingering events */
|
||||||
g_hash_table_iter_init (&iter, events_to_remove);
|
event_ids_to_remove = g_hash_table_steal_all_keys (events_to_remove);
|
||||||
while (g_hash_table_iter_next (&iter, (gpointer*) &aux, NULL))
|
if (event_ids_to_remove->len > 0)
|
||||||
remove_event_in_idle (self, aux);
|
remove_events_in_idle (self, event_ids_to_remove);
|
||||||
|
|
||||||
GCAL_EXIT;
|
GCAL_EXIT;
|
||||||
}
|
}
|
||||||
@@ -637,10 +641,13 @@ on_client_view_objects_removed_cb (ECalClientView *view,
|
|||||||
const GSList *objects,
|
const GSList *objects,
|
||||||
GcalCalendarMonitor *self)
|
GcalCalendarMonitor *self)
|
||||||
{
|
{
|
||||||
|
g_autoptr (GPtrArray) event_ids = NULL;
|
||||||
const GSList *l;
|
const GSList *l;
|
||||||
|
|
||||||
GCAL_ENTRY;
|
GCAL_ENTRY;
|
||||||
|
|
||||||
|
event_ids = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
|
||||||
for (l = objects; l; l = l->next)
|
for (l = objects; l; l = l->next)
|
||||||
{
|
{
|
||||||
g_autofree gchar *event_id = NULL;
|
g_autofree gchar *event_id = NULL;
|
||||||
@@ -678,13 +685,16 @@ on_client_view_objects_removed_cb (ECalClientView *view,
|
|||||||
while (g_hash_table_iter_next (&iter, (gpointer*) &aux, NULL))
|
while (g_hash_table_iter_next (&iter, (gpointer*) &aux, NULL))
|
||||||
{
|
{
|
||||||
if (!g_str_equal (aux, event_id) && g_str_has_prefix (aux, event_id))
|
if (!g_str_equal (aux, event_id) && g_str_has_prefix (aux, event_id))
|
||||||
remove_event_in_idle (self, aux);
|
g_ptr_array_add (event_ids, g_strdup (aux));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_event_in_idle (self, event_id);
|
g_ptr_array_add (event_ids, g_strdup (event_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event_ids->len > 0)
|
||||||
|
remove_events_in_idle (self, event_ids);
|
||||||
|
|
||||||
GCAL_EXIT;
|
GCAL_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,22 +711,8 @@ on_client_view_complete_cb (ECalClientView *view,
|
|||||||
|
|
||||||
events_to_add = g_steal_pointer (&self->monitor_thread.events_to_add);
|
events_to_add = g_steal_pointer (&self->monitor_thread.events_to_add);
|
||||||
|
|
||||||
/* Process all these instances */
|
if (events_to_add)
|
||||||
for (guint i = 0; events_to_add && i < events_to_add->len; i++)
|
add_events_in_idle (self, events_to_add);
|
||||||
{
|
|
||||||
GcalEvent *event;
|
|
||||||
|
|
||||||
if (g_cancellable_is_cancelled (self->cancellable))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event = g_ptr_array_index (events_to_add, i);
|
|
||||||
|
|
||||||
GCAL_TRACE_MSG ("Sending event '%s' (%s) to main thead's idle",
|
|
||||||
gcal_event_get_summary (event),
|
|
||||||
gcal_event_get_uid (event));
|
|
||||||
|
|
||||||
add_event_in_idle (self, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
self->monitor_thread.populated = TRUE;
|
self->monitor_thread.populated = TRUE;
|
||||||
|
|
||||||
@@ -1022,86 +1018,105 @@ set_complete (GcalCalendarMonitor *self,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
add_event_to_timeline_in_idle_cb (gpointer user_data)
|
add_events_to_timeline_in_idle_cb (gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
||||||
GcalCalendarMonitor *self;
|
GcalCalendarMonitor *self;
|
||||||
GcalEvent *event;
|
GPtrArray *events;
|
||||||
IdleData *idle_data;
|
IdleData *idle_data;
|
||||||
const gchar *event_id;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
GCAL_ENTRY;
|
||||||
|
|
||||||
idle_data = user_data;
|
idle_data = user_data;
|
||||||
self = idle_data->monitor;
|
self = idle_data->monitor;
|
||||||
event = idle_data->event;
|
events = idle_data->events;
|
||||||
g_assert (idle_data->event_id == NULL);
|
g_assert (idle_data->event_ids == NULL);
|
||||||
|
|
||||||
event_id = gcal_event_get_uid (event);
|
|
||||||
|
|
||||||
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
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)))
|
for (guint i = 0; i < events->len; i++)
|
||||||
g_signal_emit (self, signals[EVENT_ADDED], 0, event);
|
|
||||||
|
|
||||||
GCAL_RETURN (G_SOURCE_REMOVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
update_event_in_idle_cb (gpointer user_data)
|
|
||||||
{
|
|
||||||
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
|
||||||
GcalCalendarMonitor *self;
|
|
||||||
GcalEvent *old_event;
|
|
||||||
GcalEvent *event;
|
|
||||||
IdleData *idle_data;
|
|
||||||
const gchar *event_id;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
|
||||||
|
|
||||||
idle_data = user_data;
|
|
||||||
self = idle_data->monitor;
|
|
||||||
event = idle_data->event;
|
|
||||||
g_assert (idle_data->event_id == NULL);
|
|
||||||
|
|
||||||
event_id = gcal_event_get_uid (event);
|
|
||||||
|
|
||||||
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->shared.events, g_strdup (event_id), g_object_ref (event));
|
GcalEvent *event;
|
||||||
g_signal_emit (self, signals[EVENT_UPDATED], 0, old_event, event);
|
const gchar *uid;
|
||||||
|
|
||||||
|
event = g_ptr_array_index (events, i);
|
||||||
|
uid = gcal_event_get_uid (event);
|
||||||
|
|
||||||
|
if (g_hash_table_insert (self->shared.events, g_strdup (uid), g_object_ref (event)))
|
||||||
|
g_signal_emit (self, signals[EVENT_ADDED], 0, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
GCAL_RETURN (G_SOURCE_REMOVE);
|
GCAL_RETURN (G_SOURCE_REMOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
remove_event_from_timeline_in_idle_cb (gpointer user_data)
|
update_events_in_idle_cb (gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
||||||
g_autoptr (GcalEvent) event = NULL;
|
g_autoptr (GPtrArray) events = NULL;
|
||||||
GcalCalendarMonitor *self;
|
GcalCalendarMonitor *self;
|
||||||
IdleData *idle_data;
|
IdleData *idle_data;
|
||||||
gchar *event_id;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
GCAL_ENTRY;
|
||||||
|
|
||||||
idle_data = user_data;
|
idle_data = user_data;
|
||||||
self = idle_data->monitor;
|
self = idle_data->monitor;
|
||||||
g_assert (idle_data->event == NULL);
|
events = g_steal_pointer (&idle_data->events);
|
||||||
event_id = idle_data->event_id;
|
g_assert (idle_data->event_ids == NULL);
|
||||||
|
|
||||||
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
||||||
event = g_hash_table_lookup (self->shared.events, event_id);
|
for (guint i = 0; i < events->len; i++)
|
||||||
|
|
||||||
if (event)
|
|
||||||
{
|
{
|
||||||
/* Keep the event alive until the signal is emitted */
|
GcalEvent *old_event;
|
||||||
g_object_ref (event);
|
GcalEvent *event;
|
||||||
|
const gchar *event_id;
|
||||||
|
|
||||||
g_hash_table_remove (self->shared.events, event_id);
|
event = g_ptr_array_index (events, i);
|
||||||
g_signal_emit (self, signals[EVENT_REMOVED], 0, event);
|
event_id = gcal_event_get_uid (event);
|
||||||
|
|
||||||
|
old_event = g_hash_table_lookup (self->shared.events, event_id);
|
||||||
|
if (old_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GCAL_RETURN (G_SOURCE_REMOVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
remove_events_from_timeline_in_idle_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
||||||
|
g_autoptr (GPtrArray) event_ids = NULL;
|
||||||
|
GcalCalendarMonitor *self;
|
||||||
|
IdleData *idle_data;
|
||||||
|
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
|
idle_data = user_data;
|
||||||
|
self = idle_data->monitor;
|
||||||
|
event_ids = g_steal_pointer (&idle_data->event_ids);
|
||||||
|
g_assert (idle_data->events == NULL);
|
||||||
|
|
||||||
|
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
||||||
|
|
||||||
|
for (guint i = 0; i < event_ids->len; i++)
|
||||||
|
{
|
||||||
|
g_autoptr (GcalEvent) event = NULL;
|
||||||
|
const gchar *event_id;
|
||||||
|
|
||||||
|
event_id = g_ptr_array_index (event_ids, i);
|
||||||
|
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->shared.events, event_id);
|
||||||
|
g_signal_emit (self, signals[EVENT_REMOVED], 0, event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GCAL_RETURN (G_SOURCE_REMOVE);
|
GCAL_RETURN (G_SOURCE_REMOVE);
|
||||||
@@ -1133,8 +1148,8 @@ complete_in_idle_cb (gpointer user_data)
|
|||||||
|
|
||||||
idle_data = user_data;
|
idle_data = user_data;
|
||||||
self = idle_data->monitor;
|
self = idle_data->monitor;
|
||||||
g_assert (idle_data->event == NULL);
|
g_assert (idle_data->events == NULL);
|
||||||
g_assert (idle_data->event_id == NULL);
|
g_assert (idle_data->event_ids == NULL);
|
||||||
|
|
||||||
set_complete (self, idle_data->complete);
|
set_complete (self, idle_data->complete);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user