From 3c92a3d8158cf9ef30a0ef54364ad6f40323d8b9 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried 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 Origin commit data ------------------ Commit: https://github.com/neutrino-images/ni-neutrino/commit/c5ae25e66ddc23f57b6d7ecdb7c377534b26f883 Author: Stefan Seyfried Date: 2011-04-11 (Mon, 11 Apr 2011) --- 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