mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-09-01 09:51:13 +02:00
Merge branch 'ni/mp' into ni/cst-next
Conflicts:
data/icons/shutdown.jpg
data/icons/start.jpg
data/locale/Makefile.am
data/locale/deutsch.locale
data/locale/english.locale
lib/libdvbsub/dvbsub.cpp
lib/libdvbsub/dvbsubtitle.cpp
lib/libtuxtxt/tuxtxt.cpp
lib/libtuxtxt/tuxtxt.h
src/gui/dboxinfo.cpp
src/gui/movieplayer.cpp
src/gui/streaminfo2.cpp
src/gui/themes.cpp
src/neutrino.cpp
src/neutrino_menue.cpp
src/nhttpd/Makefile.am
src/system/flashtool.cpp
Origin commit data
------------------
Branch: ni/coolstream
Commit: 161347db29
Author: vanhofen <vanhofen@gmx.de>
Date: 2016-08-26 (Fri, 26 Aug 2016)
------------------
This commit was generated by Migit
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 2001 by fnbrd (fnbrd@gmx.de)
|
||||
* Homepage: http://dbox2.elxsi.de
|
||||
*
|
||||
* Copyright (C) 2008-2013 Stefan Seyfried
|
||||
* Copyright (C) 2008-2016 Stefan Seyfried
|
||||
*
|
||||
* Copyright (C) 2011-2012 CoolStream International Ltd
|
||||
*
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <eventserver.h>
|
||||
#include <driver/abstime.h>
|
||||
#include <system/helpers.h>
|
||||
#include <system/set_threadname.h>
|
||||
#include <OpenThreads/ScopedLock>
|
||||
|
||||
#include "eitd.h"
|
||||
@@ -59,7 +60,7 @@
|
||||
//#define DEBUG_SDT_THREAD
|
||||
//#define DEBUG_TIME_THREAD
|
||||
|
||||
#define DEBUG_SECTION_THREADS
|
||||
//#define DEBUG_SECTION_THREADS
|
||||
//#define DEBUG_CN_THREAD
|
||||
|
||||
/*static*/ bool reader_ready = true;
|
||||
@@ -149,10 +150,15 @@ static CFreeSatThread threadFSEIT;
|
||||
CSdtThread threadSDT;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_EVENT_LOCK
|
||||
static time_t lockstart = 0;
|
||||
#endif
|
||||
|
||||
static int sectionsd_stop = 0;
|
||||
|
||||
static bool slow_addevent = true;
|
||||
|
||||
|
||||
inline void readLockServices(void)
|
||||
{
|
||||
pthread_rwlock_rdlock(&servicesLock);
|
||||
@@ -191,10 +197,21 @@ inline void readLockEvents(void)
|
||||
inline void writeLockEvents(void)
|
||||
{
|
||||
pthread_rwlock_wrlock(&eventsLock);
|
||||
#ifdef DEBUG_EVENT_LOCK
|
||||
lockstart = time_monotonic_ms();
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -215,10 +232,11 @@ static MySIeventUniqueKeysMetaOrderServiceUniqueKey mySIeventUniqueKeysMetaOrder
|
||||
static MySIservicesOrderUniqueKey mySIservicesOrderUniqueKey;
|
||||
static MySIservicesNVODorderUniqueKey mySIservicesNVODorderUniqueKey;
|
||||
|
||||
/* needs write lock held! */
|
||||
static bool deleteEvent(const event_id_t uniqueKey)
|
||||
{
|
||||
bool ret = false;
|
||||
writeLockEvents();
|
||||
// writeLockEvents();
|
||||
MySIeventsOrderUniqueKey::iterator e = mySIeventsOrderUniqueKey.find(uniqueKey);
|
||||
|
||||
if (e != mySIeventsOrderUniqueKey.end()) {
|
||||
@@ -234,7 +252,7 @@ static bool deleteEvent(const event_id_t uniqueKey)
|
||||
mySIeventsNVODorderUniqueKey.erase(uniqueKey);
|
||||
ret = true;
|
||||
}
|
||||
unlockEvents();
|
||||
// unlockEvents();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -321,7 +339,7 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann
|
||||
unlockMessaging();
|
||||
}
|
||||
|
||||
readLockEvents();
|
||||
writeLockEvents();
|
||||
MySIeventsOrderUniqueKey::iterator si = mySIeventsOrderUniqueKey.find(evt.uniqueKey());
|
||||
bool already_exists = (si != mySIeventsOrderUniqueKey.end());
|
||||
if (already_exists && (evt.table_id < si->second->table_id))
|
||||
@@ -444,26 +462,29 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann
|
||||
delete eptr;
|
||||
return;
|
||||
}
|
||||
/* SRF special case: advertising is inserted with start time of
|
||||
* an existing event. Duration may differ. To avoid holes in EPG caused
|
||||
* by the (not useful) advertising event, don't delete the (useful)
|
||||
* original event */
|
||||
if ((*x)->table_id == e->table_id && (e->table_id & 0xFE) == 0x4e &&
|
||||
(*x)->times.begin()->startzeit == start_time)
|
||||
continue;
|
||||
/* here we have an overlapping event */
|
||||
dprintf("%s: delete 0x%012" PRIx64 ".%02x time = 0x%012" PRIx64 ".%02x\n", __func__,
|
||||
x_key, (*x)->table_id, e_key, e->table_id);
|
||||
to_delete.push_back(x_key);
|
||||
}
|
||||
}
|
||||
unlockEvents();
|
||||
|
||||
while (! to_delete.empty())
|
||||
{
|
||||
deleteEvent(to_delete.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());
|
||||
readLockEvents();
|
||||
if ( !mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.empty() && mySIeventsOrderUniqueKey.size() >= max_events && max_events != 0 ) {
|
||||
MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator lastEvent =
|
||||
mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.begin();
|
||||
@@ -498,12 +519,8 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann
|
||||
}
|
||||
event_id_t uniqueKey = (*lastEvent)->uniqueKey();
|
||||
// else fprintf(stderr, ">");
|
||||
unlockEvents();
|
||||
deleteEvent(uniqueKey);
|
||||
}
|
||||
else
|
||||
unlockEvents();
|
||||
readLockEvents();
|
||||
// Pruefen ob es ein Meta-Event ist
|
||||
MySIeventUniqueKeysMetaOrderServiceUniqueKey::iterator i = mySIeventUniqueKeysMetaOrderServiceUniqueKey.find(e->get_channel_id());
|
||||
|
||||
@@ -523,9 +540,6 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann
|
||||
// Falls das Event in den beiden Mengen mit Zeiten nicht vorhanden
|
||||
// ist, dieses dort einfuegen
|
||||
MySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey::iterator i2 = mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.find(ie->second);
|
||||
unlockEvents();
|
||||
writeLockEvents();
|
||||
|
||||
if (i2 == mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.end())
|
||||
{
|
||||
// nicht vorhanden -> einfuegen
|
||||
@@ -538,8 +552,6 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann
|
||||
}
|
||||
}
|
||||
}
|
||||
unlockEvents();
|
||||
writeLockEvents();
|
||||
// printf("Adding: %04x\n", (int) e->uniqueKey());
|
||||
|
||||
// normales Event
|
||||
@@ -567,22 +579,18 @@ static void addNVODevent(const SIevent &evt)
|
||||
|
||||
SIeventPtr e(eptr);
|
||||
|
||||
readLockEvents();
|
||||
writeLockEvents();
|
||||
MySIeventsOrderUniqueKey::iterator e2 = mySIeventsOrderUniqueKey.find(e->uniqueKey());
|
||||
|
||||
if (e2 != mySIeventsOrderUniqueKey.end())
|
||||
{
|
||||
// bisher gespeicherte Zeiten retten
|
||||
unlockEvents();
|
||||
writeLockEvents();
|
||||
e->times.insert(e2->second->times.begin(), e2->second->times.end());
|
||||
}
|
||||
unlockEvents();
|
||||
|
||||
// Damit in den nicht nach Event-ID sortierten Mengen
|
||||
// mehrere Events mit gleicher ID sind, diese vorher loeschen
|
||||
deleteEvent(e->uniqueKey());
|
||||
readLockEvents();
|
||||
if ( !mySIeventsOrderUniqueKey.empty() && mySIeventsOrderUniqueKey.size() >= max_events && max_events != 0 ) {
|
||||
//TODO: Set Old Events to 0 if limit is reached...
|
||||
MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator lastEvent =
|
||||
@@ -596,24 +604,18 @@ static void addNVODevent(const SIevent &evt)
|
||||
--lastEvent;
|
||||
}
|
||||
unlockMessaging();
|
||||
unlockEvents();
|
||||
deleteEvent((*lastEvent)->uniqueKey());
|
||||
}
|
||||
else
|
||||
unlockEvents();
|
||||
writeLockEvents();
|
||||
mySIeventsOrderUniqueKey.insert(std::make_pair(e->uniqueKey(), e));
|
||||
|
||||
mySIeventsNVODorderUniqueKey.insert(std::make_pair(e->uniqueKey(), e));
|
||||
unlockEvents();
|
||||
if (!e->times.empty())
|
||||
{
|
||||
// diese beiden Mengen enthalten nur Events mit Zeiten
|
||||
writeLockEvents();
|
||||
mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.insert(e);
|
||||
mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.insert(e);
|
||||
unlockEvents();
|
||||
}
|
||||
unlockEvents();
|
||||
}
|
||||
|
||||
static void removeOldEvents(const long seconds)
|
||||
@@ -623,7 +625,7 @@ static void removeOldEvents(const long seconds)
|
||||
// Alte events loeschen
|
||||
time_t zeit = time(NULL);
|
||||
|
||||
readLockEvents();
|
||||
writeLockEvents();
|
||||
unsigned total_events = mySIeventsOrderUniqueKey.size();
|
||||
|
||||
MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator e = mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.begin();
|
||||
@@ -642,10 +644,9 @@ static void removeOldEvents(const long seconds)
|
||||
to_delete.push_back((*e)->uniqueKey());
|
||||
++e;
|
||||
}
|
||||
unlockEvents();
|
||||
|
||||
for (std::vector<event_id_t>::iterator i = to_delete.begin(); i != to_delete.end(); ++i)
|
||||
deleteEvent(*i);
|
||||
unlockEvents();
|
||||
|
||||
readLockEvents();
|
||||
xprintf("[sectionsd] Removed %d old events (%d left), zap detected %d.\n", (int)(total_events - mySIeventsOrderUniqueKey.size()), (int)mySIeventsOrderUniqueKey.size(), messaging_zap_detected);
|
||||
@@ -1381,7 +1382,7 @@ void CTimeThread::waitForTimeset(void)
|
||||
time_mutex.unlock();
|
||||
}
|
||||
|
||||
void CTimeThread::setSystemTime(time_t tim)
|
||||
bool CTimeThread::setSystemTime(time_t tim, bool force)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm t;
|
||||
@@ -1389,6 +1390,7 @@ void CTimeThread::setSystemTime(time_t tim)
|
||||
gettimeofday(&tv, NULL);
|
||||
timediff = int64_t(tim * 1000000 - (tv.tv_usec + tv.tv_sec * 1000000));
|
||||
localtime_r(&tv.tv_sec, &t);
|
||||
int absdiff = abs(tim - tv.tv_sec);
|
||||
|
||||
xprintf("%s: timediff %" PRId64 ", current: %02d.%02d.%04d %02d:%02d:%02d, dvb: %s",
|
||||
name.c_str(), timediff,
|
||||
@@ -1400,9 +1402,9 @@ void CTimeThread::setSystemTime(time_t tim)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (timediff == 0) /* very unlikely... :-) */
|
||||
return;
|
||||
if (timeset && abs(tim - tv.tv_sec) < 120) { /* abs() is int */
|
||||
if (absdiff < 1) /* do not bother for differences less than one second */
|
||||
return true;
|
||||
if (absdiff < 120) {
|
||||
struct timeval oldd;
|
||||
tv.tv_sec = time_t(timediff / 1000000LL);
|
||||
tv.tv_usec = suseconds_t(timediff % 1000000LL);
|
||||
@@ -1412,14 +1414,21 @@ void CTimeThread::setSystemTime(time_t tim)
|
||||
xprintf("difference is < 120s, using adjtime(%d, %d). oldd(%d, %d)\n",
|
||||
(int)tv.tv_sec, (int)tv.tv_usec, (int)oldd.tv_sec, (int)oldd.tv_usec);
|
||||
timediff = 0;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
} else if (timeset && ! force) {
|
||||
xprintf("difference is > 120s, try again and set 'force=true'\n");
|
||||
return false;
|
||||
}
|
||||
/* still fall through if adjtime() failed */
|
||||
|
||||
tv.tv_sec = tim;
|
||||
tv.tv_usec = 0;
|
||||
if (settimeofday(&tv, NULL) < 0)
|
||||
perror("[sectionsd] settimeofday");
|
||||
if (settimeofday(&tv, NULL) == 0)
|
||||
return true;
|
||||
|
||||
perror("[sectionsd] settimeofday");
|
||||
return false;
|
||||
}
|
||||
|
||||
void CTimeThread::addFilters()
|
||||
@@ -1431,8 +1440,10 @@ void CTimeThread::addFilters()
|
||||
void CTimeThread::run()
|
||||
{
|
||||
time_t dvb_time = 0;
|
||||
bool retry = false; /* if time seems fishy, set to true and try again */
|
||||
xprintf("%s::run:: starting, pid %d (%lu)\n", name.c_str(), getpid(), pthread_self());
|
||||
|
||||
threadName = "sd:" + name;
|
||||
set_threadname(threadName.c_str());
|
||||
addFilters();
|
||||
DMX::start();
|
||||
|
||||
@@ -1474,7 +1485,21 @@ void CTimeThread::run()
|
||||
|
||||
xprintf("%s: get DVB time ch 0x%012" PRIx64 " (isOpen %d)\n",
|
||||
name.c_str(), current_service, isOpen());
|
||||
int rc = dmx->Read(static_buf, MAX_SECTION_LENGTH, timeoutInMSeconds);
|
||||
int rc;
|
||||
#if HAVE_COOL_HARDWARE
|
||||
/* libcoolstream does not like the repeated read if the dmx is not yet running
|
||||
* (e.g. during neutrino start) and causes strange openthreads errors which in
|
||||
* turn cause complete malfunction of the dmx, so we cannot use the "speed up
|
||||
* shutdown" hack on with libcoolstream... :-( */
|
||||
rc = dmx->Read(static_buf, MAX_SECTION_LENGTH, timeoutInMSeconds);
|
||||
#else
|
||||
time_t start = time_monotonic_ms();
|
||||
/* speed up shutdown by looping around Read() */
|
||||
do {
|
||||
rc = dmx->Read(static_buf, MAX_SECTION_LENGTH, timeoutInMSeconds / 12);
|
||||
} while (running && rc == 0
|
||||
&& (time_monotonic_ms() - start) < (time_t)timeoutInMSeconds);
|
||||
#endif
|
||||
xprintf("%s: get DVB time ch 0x%012" PRIx64 " rc: %d neutrino_sets_time %d\n",
|
||||
name.c_str(), current_service, rc, messaging_neutrino_sets_time);
|
||||
if (rc > 0) {
|
||||
@@ -1489,7 +1514,14 @@ void CTimeThread::run()
|
||||
sleep_time = ntprefresh * 60;
|
||||
if(success) {
|
||||
if(dvb_time) {
|
||||
setSystemTime(dvb_time);
|
||||
bool ret = setSystemTime(dvb_time, retry);
|
||||
if (! ret) {
|
||||
xprintf("%s: time looks wrong, trying again\n", name.c_str());
|
||||
sendToSleepNow = false;
|
||||
retry = true;
|
||||
continue;
|
||||
}
|
||||
retry = false;
|
||||
/* retry a second time immediately after start, to get TOT ? */
|
||||
if(first_time)
|
||||
sleep_time = 5;
|
||||
@@ -1546,6 +1578,8 @@ int CSectionThread::Sleep()
|
||||
void CSectionThread::run()
|
||||
{
|
||||
xprintf("%s::run:: starting, pid %d (%lu)\n", name.c_str(), getpid(), pthread_self());
|
||||
threadName = "sd:" + name;
|
||||
set_threadname(threadName.c_str());
|
||||
if (sections_debug)
|
||||
dump_sched_info(name);
|
||||
|
||||
@@ -2078,10 +2112,14 @@ static void *houseKeepingThread(void *)
|
||||
count = 0;
|
||||
}
|
||||
|
||||
int rc = HOUSEKEEPING_SLEEP;
|
||||
int i = HOUSEKEEPING_SLEEP;
|
||||
|
||||
while (rc)
|
||||
rc = sleep(rc);
|
||||
while (i > 0 && !sectionsd_stop) {
|
||||
sleep(1);
|
||||
i--;
|
||||
}
|
||||
if (sectionsd_stop)
|
||||
break;
|
||||
|
||||
if (!scanning) {
|
||||
scount++;
|
||||
@@ -2210,6 +2248,7 @@ void CEitManager::run()
|
||||
int rc;
|
||||
|
||||
xprintf("[sectionsd] starting\n");
|
||||
set_threadname("sd:eitmanager");
|
||||
printf("SIevent size: %d\n", (int)sizeof(SIevent));
|
||||
|
||||
/* "export NO_SLOW_ADDEVENT=true" to disable this */
|
||||
@@ -2292,7 +2331,12 @@ printf("SIevent size: %d\n", (int)sizeof(SIevent));
|
||||
|
||||
xprintf("pausing...\n");
|
||||
|
||||
/* sometimes, pthread_cancel seems to not work, maybe it is a bad idea to mix
|
||||
* plain pthread and OpenThreads? */
|
||||
sectionsd_stop = 1;
|
||||
pthread_cancel(threadHouseKeeping);
|
||||
xprintf("join Housekeeping\n");
|
||||
pthread_join(threadHouseKeeping, NULL);
|
||||
|
||||
xprintf("join TOT\n");
|
||||
threadTIME.Stop();
|
||||
@@ -2789,7 +2833,7 @@ void CEitManager::getChannelEvents(CChannelEventList &eList, t_channel_id *chidl
|
||||
bool found_already = true;
|
||||
time_t azeit = time(NULL);
|
||||
|
||||
showProfiling("sectionsd_getChannelEvents start");
|
||||
// showProfiling("sectionsd_getChannelEvents start");
|
||||
readLockEvents();
|
||||
|
||||
/* !!! FIX ME: if the box starts on a channel where there is no EPG sent, it hangs!!! */
|
||||
@@ -2833,7 +2877,7 @@ showProfiling("sectionsd_getChannelEvents start");
|
||||
}
|
||||
}
|
||||
|
||||
showProfiling("sectionsd_getChannelEvents end");
|
||||
// showProfiling("sectionsd_getChannelEvents end");
|
||||
unlockEvents();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user