From c5ae25e66ddc23f57b6d7ecdb7c377534b26f883 Mon Sep 17 00:00:00 2001 From: seife Date: Mon, 11 Apr 2011 17:17:37 +0000 Subject: [PATCH] sectionsd: un-break removeDupEvents() The crashes probably were caused by the iterator being invalid due to concurrent insertion and deletion of events. An obvious fix is to collect the list of events to delete while holding the read lock, and later deleting them all in an extra loop. Turned out to be less complicated than I originally expected ;) TODO: audit the sectionsd code for similar stuff in other places. git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@1391 e54a6e83-5905-42d5-8d5c-058d10e6a962 --- src/sectionsd/sectionsd.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/sectionsd/sectionsd.cpp b/src/sectionsd/sectionsd.cpp index 851e9c595..c85298e64 100644 --- a/src/sectionsd/sectionsd.cpp +++ b/src/sectionsd/sectionsd.cpp @@ -1212,6 +1212,8 @@ static void removeOldEvents(const long seconds) static void removeDupEvents(void) { MySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey::iterator e1, e2, del; + /* list of event IDs to delete */ + std::vectorto_delete; readLockEvents(); e1 = mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.begin(); @@ -1238,23 +1240,23 @@ static void removeDupEvents(void) continue; } - del = mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.end(); if ((*e1)->table_id > (*e2)->table_id) del = e1; if ((*e1)->table_id < (*e2)->table_id) del = e2; - /* can not happen. This check is pure paranoia :) */ - if (del == mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.end()) - continue; - xprintf("%s: removing event %llx.%02x '%s'\n", __func__, (*del)->uniqueKey(), (*del)->table_id, (*del)->getName().c_str()); - unlockEvents(); - deleteEvent((*del)->uniqueKey()); - readLockEvents(); + /* remember the unique ID for later deletion */ + to_delete.push_back((*del)->uniqueKey()); } unlockEvents(); + + /* clean up outside of the iterator loop */ + for (std::vector::iterator i = to_delete.begin(); i != to_delete.end(); i++) + deleteEvent(*i); + to_delete.clear(); /* needed? can't hurt... */ + return; } @@ -8293,14 +8295,11 @@ printf("[sectionsd] Removed %d old events.\n", anzEventsAlt - mySIeventsOrderUni unlockEvents(); // usleep(100); // lockEvents(); -#ifdef USE_BROKEN_REMOVE_DUP_EVENTS - /* this is currently broken */ removeDupEvents(); readLockEvents(); printf("[sectionsd] Removed %d dup events.\n", anzEventsAlt - mySIeventsOrderUniqueKey.size()); anzEventsAlt = mySIeventsOrderUniqueKey.size(); unlockEvents(); -#endif dprintf("before removewasteepg\n"); #ifdef UPDATE_NETWORKS removeWasteEvents(); // Events for channels not in services.xml