gcal-timeline: never reset completed_calendars

Since 78cb11c64d, GcalCalendarMonitor now
notifies when a completed calendar transitions to incomplete, and
GcalTimeline decrements its completed_calendars counter. But we forgot
to remove the code that resets completed_calendars when previously
needed. That's not required anymore, because we can trust
GcalCalendarMonitor to do the right thing.

In my case, I have 5 calendars enabled and 6 total. When starting
gnome-calendar, all 5 are successively completed, and
completed_calendars increments from 0 -> 1 -> 2 -> 3 -> 4 -> 5. Then,
when transitioning month view from January 2020 to December 2019, we
call reset_completed_calendars() and completed_calenders gets clobbered
to 0. Then it decrements from 0 -> -1 -> -2 -> -3 -> -4 -> -5 as the
GcalCalendarMonitors notify that they are no longer completed. Well,
that is what would happen, if it didn't crash when decrementing to -1.
We assert -1 <= 6 (the total number of calendars) and crash because -1
gets promoted to a huge unsigned int, since we're comparing signed to
unsigned. (That crash would have been avoided if we used
-Wsign-compare, although that warning would not have caught the logic
problem.)

Anyway, since GcalMonitor now notifies when calendars are no longer
complete, it is safe to simply remove reset_completed_calendars().
GcalTimeline will still notify if it needs to change its own complete
property (in on_calendar_monitor_completed_cb).

Fixes #567
Fixes #636
Fixes #638
Fixes #647
Fixes #650
This commit is contained in:
Michael Catanzaro
2020-10-14 09:13:12 -05:00
parent f18d4121bf
commit c2c89b667e
+1 -19
View File
@@ -194,16 +194,6 @@ is_timeline_complete (GcalTimeline *self)
return self->completed_calendars == g_hash_table_size (self->calendars);
}
static void
reset_completed_calendars (GcalTimeline *self)
{
gboolean was_complete = is_timeline_complete (self);
self->completed_calendars = 0;
if (is_timeline_complete (self) != was_complete)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMPLETE]);
}
static void
add_event_to_subscriber (GcalTimelineSubscriber *subscriber,
GcalEvent *event)
@@ -294,8 +284,6 @@ update_range (GcalTimeline *self)
{
GcalCalendarMonitor *monitor;
reset_completed_calendars (self);
g_hash_table_iter_init (&iter, self->calendars);
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &monitor))
gcal_calendar_monitor_set_range (monitor, self->range);
@@ -480,8 +468,6 @@ update_calendar_monitor_filters (GcalTimeline *self)
GcalCalendarMonitor *monitor;
GHashTableIter iter;
reset_completed_calendars (self);
g_hash_table_iter_init (&iter, self->calendars);
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &monitor))
gcal_calendar_monitor_set_filter (monitor, self->filter);
@@ -1027,12 +1013,8 @@ gcal_timeline_remove_subscriber (GcalTimeline *self,
g_signal_handlers_disconnect_by_func (subscriber, on_subscriber_range_changed_cb, self);
g_hash_table_remove (self->subscribers, subscriber);
/* If all subscribers were removed, reset the complete counter */
if (g_hash_table_size (self->subscribers) == 0)
{
g_queue_clear_full (self->event_queue, (GDestroyNotify) queue_data_free);
reset_completed_calendars (self);
}
g_queue_clear_full (self->event_queue, (GDestroyNotify) queue_data_free);
gcal_range_tree_remove_data (self->subscriber_ranges, subscriber);
update_range (self);