mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-30 17:01:15 +02:00
sectionsd: fix unlocked event access under high load
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
* Copyright (C) 2001 by fnbrd (fnbrd@gmx.de)
|
* Copyright (C) 2001 by fnbrd (fnbrd@gmx.de)
|
||||||
* Homepage: http://dbox2.elxsi.de
|
* Homepage: http://dbox2.elxsi.de
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008, 2009 Stefan Seyfried
|
* Copyright (C) 2008, 2009, 2010, 2011, 2012 Stefan Seyfried
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2012 CoolStream International Ltd
|
* Copyright (C) 2011-2012 CoolStream International Ltd
|
||||||
*
|
*
|
||||||
@@ -141,10 +141,15 @@ static CFreeSatThread threadFSEIT;
|
|||||||
CSdtThread threadSDT;
|
CSdtThread threadSDT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_EVENT_LOCK
|
||||||
|
static time_t lockstart = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
static int sectionsd_stop = 0;
|
static int sectionsd_stop = 0;
|
||||||
|
|
||||||
static bool slow_addevent = true;
|
static bool slow_addevent = true;
|
||||||
|
|
||||||
|
|
||||||
inline void readLockServices(void)
|
inline void readLockServices(void)
|
||||||
{
|
{
|
||||||
pthread_rwlock_rdlock(&servicesLock);
|
pthread_rwlock_rdlock(&servicesLock);
|
||||||
@@ -183,10 +188,21 @@ inline void readLockEvents(void)
|
|||||||
inline void writeLockEvents(void)
|
inline void writeLockEvents(void)
|
||||||
{
|
{
|
||||||
pthread_rwlock_wrlock(&eventsLock);
|
pthread_rwlock_wrlock(&eventsLock);
|
||||||
|
#ifdef DEBUG_EVENT_LOCK
|
||||||
|
lockstart = time_monotonic_ms();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unlockEvents(void)
|
inline void unlockEvents(void)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_EVENT_LOCK
|
||||||
|
if (lockstart) {
|
||||||
|
time_t tmp = time_monotonic_ms() - lockstart;
|
||||||
|
if (tmp > 50)
|
||||||
|
xprintf("locked ms %d\n", tmp);
|
||||||
|
lockstart = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
pthread_rwlock_unlock(&eventsLock);
|
pthread_rwlock_unlock(&eventsLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,10 +223,11 @@ static MySIeventUniqueKeysMetaOrderServiceUniqueKey mySIeventUniqueKeysMetaOrder
|
|||||||
static MySIservicesOrderUniqueKey mySIservicesOrderUniqueKey;
|
static MySIservicesOrderUniqueKey mySIservicesOrderUniqueKey;
|
||||||
static MySIservicesNVODorderUniqueKey mySIservicesNVODorderUniqueKey;
|
static MySIservicesNVODorderUniqueKey mySIservicesNVODorderUniqueKey;
|
||||||
|
|
||||||
|
/* needs write lock held! */
|
||||||
static bool deleteEvent(const event_id_t uniqueKey)
|
static bool deleteEvent(const event_id_t uniqueKey)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
writeLockEvents();
|
// writeLockEvents();
|
||||||
MySIeventsOrderUniqueKey::iterator e = mySIeventsOrderUniqueKey.find(uniqueKey);
|
MySIeventsOrderUniqueKey::iterator e = mySIeventsOrderUniqueKey.find(uniqueKey);
|
||||||
|
|
||||||
if (e != mySIeventsOrderUniqueKey.end()) {
|
if (e != mySIeventsOrderUniqueKey.end()) {
|
||||||
@@ -226,7 +243,7 @@ static bool deleteEvent(const event_id_t uniqueKey)
|
|||||||
mySIeventsNVODorderUniqueKey.erase(uniqueKey);
|
mySIeventsNVODorderUniqueKey.erase(uniqueKey);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
unlockEvents();
|
// unlockEvents();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +328,7 @@ xprintf("addEvent: current %016llx event %016llx running %d messaging_got_CN %d\
|
|||||||
unlockMessaging();
|
unlockMessaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
readLockEvents();
|
writeLockEvents();
|
||||||
MySIeventsOrderUniqueKey::iterator si = mySIeventsOrderUniqueKey.find(evt.uniqueKey());
|
MySIeventsOrderUniqueKey::iterator si = mySIeventsOrderUniqueKey.find(evt.uniqueKey());
|
||||||
bool already_exists = (si != mySIeventsOrderUniqueKey.end());
|
bool already_exists = (si != mySIeventsOrderUniqueKey.end());
|
||||||
if (already_exists && (evt.table_id < si->second->table_id))
|
if (already_exists && (evt.table_id < si->second->table_id))
|
||||||
@@ -424,20 +441,16 @@ xprintf("addEvent: current %016llx event %016llx running %d messaging_got_CN %d\
|
|||||||
to_delete.push_back(x_key);
|
to_delete.push_back(x_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlockEvents();
|
|
||||||
|
|
||||||
while (! to_delete.empty())
|
while (! to_delete.empty())
|
||||||
{
|
{
|
||||||
deleteEvent(to_delete.back());
|
deleteEvent(to_delete.back());
|
||||||
to_delete.pop_back();
|
to_delete.pop_back();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Damit in den nicht nach Event-ID sortierten Mengen
|
|
||||||
// Mehrere Events mit gleicher ID sind, diese vorher loeschen
|
|
||||||
unlockEvents();
|
|
||||||
}
|
}
|
||||||
|
// Damit in den nicht nach Event-ID sortierten Mengen
|
||||||
|
// Mehrere Events mit gleicher ID sind, diese vorher loeschen
|
||||||
deleteEvent(e->uniqueKey());
|
deleteEvent(e->uniqueKey());
|
||||||
readLockEvents();
|
|
||||||
if ( !mySIeventsOrderUniqueKey.empty() && mySIeventsOrderUniqueKey.size() >= max_events && max_events != 0 ) {
|
if ( !mySIeventsOrderUniqueKey.empty() && mySIeventsOrderUniqueKey.size() >= max_events && max_events != 0 ) {
|
||||||
MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator lastEvent =
|
MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator lastEvent =
|
||||||
mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.begin();
|
mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.begin();
|
||||||
@@ -471,12 +484,8 @@ xprintf("addEvent: current %016llx event %016llx running %d messaging_got_CN %d\
|
|||||||
unlockMessaging();
|
unlockMessaging();
|
||||||
}
|
}
|
||||||
// else fprintf(stderr, ">");
|
// else fprintf(stderr, ">");
|
||||||
unlockEvents();
|
|
||||||
deleteEvent((*lastEvent)->uniqueKey());
|
deleteEvent((*lastEvent)->uniqueKey());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
unlockEvents();
|
|
||||||
readLockEvents();
|
|
||||||
// Pruefen ob es ein Meta-Event ist
|
// Pruefen ob es ein Meta-Event ist
|
||||||
MySIeventUniqueKeysMetaOrderServiceUniqueKey::iterator i = mySIeventUniqueKeysMetaOrderServiceUniqueKey.find(e->get_channel_id());
|
MySIeventUniqueKeysMetaOrderServiceUniqueKey::iterator i = mySIeventUniqueKeysMetaOrderServiceUniqueKey.find(e->get_channel_id());
|
||||||
|
|
||||||
@@ -496,9 +505,6 @@ xprintf("addEvent: current %016llx event %016llx running %d messaging_got_CN %d\
|
|||||||
// Falls das Event in den beiden Mengen mit Zeiten nicht vorhanden
|
// Falls das Event in den beiden Mengen mit Zeiten nicht vorhanden
|
||||||
// ist, dieses dort einfuegen
|
// ist, dieses dort einfuegen
|
||||||
MySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey::iterator i2 = mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.find(ie->second);
|
MySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey::iterator i2 = mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.find(ie->second);
|
||||||
unlockEvents();
|
|
||||||
writeLockEvents();
|
|
||||||
|
|
||||||
if (i2 == mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.end())
|
if (i2 == mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.end())
|
||||||
{
|
{
|
||||||
// nicht vorhanden -> einfuegen
|
// nicht vorhanden -> einfuegen
|
||||||
@@ -511,8 +517,6 @@ xprintf("addEvent: current %016llx event %016llx running %d messaging_got_CN %d\
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlockEvents();
|
|
||||||
writeLockEvents();
|
|
||||||
// printf("Adding: %04x\n", (int) e->uniqueKey());
|
// printf("Adding: %04x\n", (int) e->uniqueKey());
|
||||||
|
|
||||||
// normales Event
|
// normales Event
|
||||||
@@ -540,22 +544,18 @@ static void addNVODevent(const SIevent &evt)
|
|||||||
|
|
||||||
SIeventPtr e(eptr);
|
SIeventPtr e(eptr);
|
||||||
|
|
||||||
readLockEvents();
|
writeLockEvents();
|
||||||
MySIeventsOrderUniqueKey::iterator e2 = mySIeventsOrderUniqueKey.find(e->uniqueKey());
|
MySIeventsOrderUniqueKey::iterator e2 = mySIeventsOrderUniqueKey.find(e->uniqueKey());
|
||||||
|
|
||||||
if (e2 != mySIeventsOrderUniqueKey.end())
|
if (e2 != mySIeventsOrderUniqueKey.end())
|
||||||
{
|
{
|
||||||
// bisher gespeicherte Zeiten retten
|
// bisher gespeicherte Zeiten retten
|
||||||
unlockEvents();
|
|
||||||
writeLockEvents();
|
|
||||||
e->times.insert(e2->second->times.begin(), e2->second->times.end());
|
e->times.insert(e2->second->times.begin(), e2->second->times.end());
|
||||||
}
|
}
|
||||||
unlockEvents();
|
|
||||||
|
|
||||||
// Damit in den nicht nach Event-ID sortierten Mengen
|
// Damit in den nicht nach Event-ID sortierten Mengen
|
||||||
// mehrere Events mit gleicher ID sind, diese vorher loeschen
|
// mehrere Events mit gleicher ID sind, diese vorher loeschen
|
||||||
deleteEvent(e->uniqueKey());
|
deleteEvent(e->uniqueKey());
|
||||||
readLockEvents();
|
|
||||||
if ( !mySIeventsOrderUniqueKey.empty() && mySIeventsOrderUniqueKey.size() >= max_events && max_events != 0 ) {
|
if ( !mySIeventsOrderUniqueKey.empty() && mySIeventsOrderUniqueKey.size() >= max_events && max_events != 0 ) {
|
||||||
//TODO: Set Old Events to 0 if limit is reached...
|
//TODO: Set Old Events to 0 if limit is reached...
|
||||||
MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator lastEvent =
|
MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator lastEvent =
|
||||||
@@ -569,24 +569,18 @@ static void addNVODevent(const SIevent &evt)
|
|||||||
--lastEvent;
|
--lastEvent;
|
||||||
}
|
}
|
||||||
unlockMessaging();
|
unlockMessaging();
|
||||||
unlockEvents();
|
|
||||||
deleteEvent((*lastEvent)->uniqueKey());
|
deleteEvent((*lastEvent)->uniqueKey());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
unlockEvents();
|
|
||||||
writeLockEvents();
|
|
||||||
mySIeventsOrderUniqueKey.insert(std::make_pair(e->uniqueKey(), e));
|
mySIeventsOrderUniqueKey.insert(std::make_pair(e->uniqueKey(), e));
|
||||||
|
|
||||||
mySIeventsNVODorderUniqueKey.insert(std::make_pair(e->uniqueKey(), e));
|
mySIeventsNVODorderUniqueKey.insert(std::make_pair(e->uniqueKey(), e));
|
||||||
unlockEvents();
|
|
||||||
if (!e->times.empty())
|
if (!e->times.empty())
|
||||||
{
|
{
|
||||||
// diese beiden Mengen enthalten nur Events mit Zeiten
|
// diese beiden Mengen enthalten nur Events mit Zeiten
|
||||||
writeLockEvents();
|
|
||||||
mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.insert(e);
|
mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.insert(e);
|
||||||
mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.insert(e);
|
mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.insert(e);
|
||||||
unlockEvents();
|
|
||||||
}
|
}
|
||||||
|
unlockEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void removeOldEvents(const long seconds)
|
static void removeOldEvents(const long seconds)
|
||||||
@@ -596,7 +590,7 @@ static void removeOldEvents(const long seconds)
|
|||||||
// Alte events loeschen
|
// Alte events loeschen
|
||||||
time_t zeit = time(NULL);
|
time_t zeit = time(NULL);
|
||||||
|
|
||||||
readLockEvents();
|
writeLockEvents();
|
||||||
|
|
||||||
MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator e = mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.begin();
|
MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator e = mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.begin();
|
||||||
|
|
||||||
@@ -614,10 +608,9 @@ static void removeOldEvents(const long seconds)
|
|||||||
to_delete.push_back((*e)->uniqueKey());
|
to_delete.push_back((*e)->uniqueKey());
|
||||||
++e;
|
++e;
|
||||||
}
|
}
|
||||||
unlockEvents();
|
|
||||||
|
|
||||||
for (std::vector<event_id_t>::iterator i = to_delete.begin(); i != to_delete.end(); ++i)
|
for (std::vector<event_id_t>::iterator i = to_delete.begin(); i != to_delete.end(); ++i)
|
||||||
deleteEvent(*i);
|
deleteEvent(*i);
|
||||||
|
unlockEvents();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user