1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
#include <pch.hpp>
#include <logger.h>
#include <thread>
#include "maintenance.h"
#include <Ice/Ice.h>
#include "bindTimerTask.h"
#include <linux/dvb/frontend.h>
#include <cxxabi.h>
time_t Maintenance::periodUpdateNetwork;
time_t Maintenance::periodUpdateServices;
time_t Maintenance::periodUpdateEvents;
bool Maintenance::scanOnStart;
DECLARE_OPTIONS(Maintenance, "P2PVR Maintenance options")
("p2pvr.maintenance.periodUpdateNetwork", Options::value(&periodUpdateNetwork, 86400 * 7),
"Period between automated updates of DVB network (1 week)")
("p2pvr.maintenance.periodUpdateServices", Options::value(&periodUpdateServices, 86400 * 7),
"Period between automated updates of DVB services (1 week)")
("p2pvr.maintenance.periodUpdateEvents", Options::value(&periodUpdateEvents, 3600 * 12),
"Period between automated updates of DVB events (12 hours)")
("p2pvr.maintenance.scanOnStart", Options::value(&scanOnStart, false),
"Perform the maintenance circle on start-up (false)")
END_OPTIONS(Maintenance);
Maintenance::Maintenance(Ice::ObjectAdapterPtr a, IceUtil::TimerPtr t) :
adapter(a),
timer(t),
clientCheck(new BindTimerTask(boost::bind(&Maintenance::ScheduledUpdate, this))),
lastUpdateNetwork(0),
lastUpdateServices(0),
lastUpdateEvents(0),
updateRunning(false)
{
if (timer) {
timer->scheduleRepeated(clientCheck, IceUtil::Time::seconds(5 * 60));
}
if (scanOnStart) {
ScheduledUpdate();
}
}
void
Maintenance::UpdateAll(const Ice::Current & ice)
{
UpdateAll(FE_OFDM, ice);
UpdateAll(FE_QPSK, ice);
UpdateAll(FE_ATSC, ice);
UpdateAll(FE_QAM, ice);
}
void
Maintenance::UpdateAll(short type, const Ice::Current & ice)
{
UpdateNetwork(type, ice);
UpdateServices(ice);
UpdateEvents(ice);
}
void
Maintenance::ScheduledUpdate()
{
Logger()->messagebf(LOG_DEBUG, "%s: triggered", __PRETTY_FUNCTION__);
if (!updateRunning) {
std::thread update([this] {
try {
AdHoc::ScopeExit notRunning([this]{ updateRunning = false; });
updateRunning = true;
auto si = P2PVR::MaintenancePrx::checkedCast(adapter->createProxy(adapter->getCommunicator()->stringToIdentity("Maintenance")));
time_t now = time(NULL);
if (lastUpdateNetwork < now - periodUpdateNetwork) {
Logger()->messagebf(LOG_INFO, "%s: updating network", __PRETTY_FUNCTION__);
si->UpdateNetwork(FE_OFDM);
time(&lastUpdateNetwork);
}
if (lastUpdateServices < now - periodUpdateServices) {
Logger()->messagebf(LOG_INFO, "%s: updating services", __PRETTY_FUNCTION__);
si->UpdateServices();
time(&lastUpdateServices);
}
if (lastUpdateEvents < now - periodUpdateEvents) {
Logger()->messagebf(LOG_INFO, "%s: updating events", __PRETTY_FUNCTION__);
si->UpdateEvents();
time(&lastUpdateEvents);
}
Logger()->messagebf(LOG_DEBUG, "%s: completed", __PRETTY_FUNCTION__);
}
catch (const std::exception & ex) {
char * buf = __cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL);
Logger()->messagebf(LOG_ERR, "%s: failed %s: %s", __PRETTY_FUNCTION__, buf, ex.what());
free(buf);
}
catch (...) {
Logger()->messagebf(LOG_ERR, "%s: failed (unknown exception)", __PRETTY_FUNCTION__);
}
});
update.detach();
}
}
|