summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vdr-vdrmanager/helpers.cpp182
-rw-r--r--vdr-vdrmanager/helpers.h14
2 files changed, 120 insertions, 76 deletions
diff --git a/vdr-vdrmanager/helpers.cpp b/vdr-vdrmanager/helpers.cpp
index cc9dedb..7cbca5d 100644
--- a/vdr-vdrmanager/helpers.cpp
+++ b/vdr-vdrmanager/helpers.cpp
@@ -25,6 +25,49 @@
#define INDEXFILESUFFIX "/index.vdr"
#define LENGTHFILESUFFIX "/length.vdr"
+#ifdef DEF_LIST_LOCK
+
+#define READ_LOCK_BASE(Class, Define) LOCK_##Define##_READ; const c##Class * the##Class = Class
+#define WRITE_LOCK_BASE(Class, Define) LOCK_##Define##_WRITE; c##Class * the##Class = Class
+
+#define READ_LOCK_TIMERS READ_LOCK_BASE(Timers, TIMERS)
+#define WRITE_LOCK_TIMERS WRITE_LOCK_BASE(Timers, TIMERS)
+
+#define READ_LOCK_RECORDINGS READ_LOCK_BASE(Recordings, RECORDINGS)
+#define WRITE_LOCK_RECORDINGS WRITE_LOCK_BASE(Recordings, RECORDINGS)
+
+#define READ_LOCK_CHANNELS READ_LOCK_BASE(Channels, CHANNELS)
+#define WRITE_LOCK_CHANNELS WRITE_LOCK_BASE(Channels, CHANNELS)
+
+#define READ_LOCK_SCHEDULES READ_LOCK_BASE(Schedules, SCHEDULES)
+#define WRITE_LOCK_SCHEDULES WRITE_LOCK_BASE(Schedules, SCHEDULES)
+
+#define RECORDING_CONTROLS_PROCESS cRecordControls::Process(theTimers, time(NULL))
+#define LIST_ELEM_CONST const
+
+#else
+
+#define READ_LOCK_BASE(Class) c##Class * the##Class = &Class
+#define WRITE_LOCK_BASE(Class) c##Class * the##Class = &Class
+
+#define READ_LOCK_TIMERS READ_LOCK_BASE(Timers)
+#define WRITE_LOCK_TIMERS WRITE_LOCK_BASE(Timers)
+
+#define READ_LOCK_RECORDINGS READ_LOCK_BASE(Recordings)
+#define WRITE_LOCK_RECORDINGS WRITE_LOCK_BASE(Recordings)
+
+#define READ_LOCK_CHANNELS READ_LOCK_BASE(Channels)
+#define WRITE_LOCK_CHANNELS WRITE_LOCK_BASE(Channels)
+
+#define LOCKED_SCHEDULES cSchedulesLock schedulesLock; const cSchedules * theSchedules = cSchedules::Schedules(schedulesLock);
+#define READ_LOCK_SCHEDULES LOCKED_SCHEDULES
+#define WRITE_LOCK_SCHEDULES LOCKED_SCHEDULES
+
+#define RECORDING_CONTROLS_PROCESS cRecordControls::Process(time(NULL))
+#define LIST_ELEM_CONST
+
+#endif
+
static char ServiceInterface[] = "Epgsearch-services-v1.1";
string cHelpers::GetRecordings(string args) {
@@ -103,7 +146,8 @@ string cHelpers::GetTimersIntern(string options) {
string result = "START\r\n";
// iterate through all timers
- for (cTimer * timer = Timers.First(); timer; timer = Timers.Next(timer)) {
+ READ_LOCK_TIMERS;
+ for (const cTimer * timer = theTimers->First(); timer; timer = theTimers->Next(timer)) {
result += ToText(timer, conflicts);
}
@@ -127,9 +171,10 @@ string cHelpers::GetRecordingsIntern() {
string result = sstm.str();
//iterate through all recordings
- cRecording* recording = NULL;
- for (int i = 0; i < Recordings.Count(); i++) {
- recording = Recordings.Get(i);
+ READ_LOCK_RECORDINGS;
+ const cRecording* recording = NULL;
+ for (int i = 0; i < theRecordings->Count(); i++) {
+ recording = theRecordings->Get(i);
result += ToText(recording);
}
return result + "END\r\n";
@@ -141,8 +186,9 @@ string cHelpers::GetChannelsIntern(string wantedChannels) {
string currentGroup = "";
char number[10];
- for (cChannel * channel = Channels.First(); channel; channel =
- Channels.Next(channel)) {
+ READ_LOCK_CHANNELS;
+ for (const cChannel * channel = theChannels->First(); channel; channel =
+ theChannels->Next(channel)) {
// channel group
if (channel->GroupSep()) {
@@ -186,7 +232,7 @@ string cHelpers::SetChannelIntern(const string args) {
return "!ERROR:SetChannel;empty args\r\n";
}
- cChannel *channel;
+ const cChannel *channel;
bool isnum = true;
for (int i = 0; i < (int) args.length(); i++) {
if (!std::isdigit(args[i])) {
@@ -196,12 +242,13 @@ string cHelpers::SetChannelIntern(const string args) {
}
+ READ_LOCK_CHANNELS;
if (isnum) {
int nr = atoi(args.c_str());
- channel = Channels.GetByNumber(nr);
+ channel = theChannels->GetByNumber(nr);
} else {
tChannelID chid = tChannelID::FromString(args.c_str());
- channel = Channels.GetByChannelID(chid);
+ channel = theChannels->GetByChannelID(chid);
}
if (!channel) {
@@ -259,21 +306,21 @@ string cHelpers::GetEventsIntern(string wantedChannels, string when) {
string result = "START\r\n";
- cSchedulesLock schedulesLock;
- const cSchedules * schedules = cSchedules::Schedules(schedulesLock);
- for (cSchedule * schedule = schedules->First(); schedule; schedule =
- schedules->Next(schedule)) {
+ READ_LOCK_SCHEDULES;
+ READ_LOCK_CHANNELS;
+ for (const cSchedule * schedule = theSchedules->First(); schedule; schedule =
+ theSchedules->Next(schedule)) {
- cChannel * channel = Channels.GetByChannelID(schedule->ChannelID());
+ const cChannel * channel = theChannels->GetByChannelID(schedule->ChannelID());
if (!IsWantedChannel(channel, wantedChannels)) {
continue;
}
const cList<cEvent> * events = schedule->Events();
- for (cEvent * event = events->First(); event;
+ for (const cEvent * event = events->First(); event;
event = events->Next(event)) {
if (IsWantedTime(wantedTime, event)) {
- cEvent * match = event;
+ const cEvent * match = event;
if (when == "NEXT") {
match = events->Next(match);
if (!match) {
@@ -307,7 +354,8 @@ string cHelpers::DelRecording(cRecording * recording) {
#else
if (RecordingsHandler.GetUsage(FileName)) {
RecordingsHandler.Del(FileName);
- recording = Recordings.GetByName(FileName); // RecordingsHandler.Del() might have deleted it if it was the edited version
+ WRITE_LOCK_RECORDINGS;
+ recording = theRecordings->GetByName(FileName); // RecordingsHandler.Del() might have deleted it if it was the edited version
// we continue with the code below even if recording is NULL,
// in order to have the menu updated etc.
}
@@ -318,9 +366,10 @@ string cHelpers::DelRecording(cRecording * recording) {
cControl::Shutdown();
}
+ WRITE_LOCK_RECORDINGS;
if (!recording || recording->Delete()) {
cReplayControl::ClearLastReplayed(FileName);
- Recordings.DelByName(FileName);
+ theRecordings->DelByName(FileName);
#if VDRVERSNUM > 10727
cVideoDiskUsage::ForceCheck();
#endif
@@ -337,7 +386,11 @@ string cHelpers::DelRecordingIntern(string args) {
int index = atoi(args.c_str());
- cRecording *recording = Recordings.Get(index);
+ cRecording *recording = NULL;
+ {
+ WRITE_LOCK_RECORDINGS;
+ recording = theRecordings->Get(index);
+ }
if (!recording) {
return Error("Recording not found");
}
@@ -362,12 +415,13 @@ string cHelpers::DelRecordingIntern(string args) {
cTimer *timer = rc->Timer();
if (timer) {
timer->Skip();
- cRecordControls::Process(time(NULL));
+ WRITE_LOCK_TIMERS;
+ RECORDING_CONTROLS_PROCESS;
if (timer->IsSingleEvent()) {
isyslog("deleting timer %s", *timer->ToDescr());
- Timers.Del(timer);
+ theTimers->Del(timer);
}
- Timers.SetModified();
+ theTimers->SetModified();
}
return cHelpers::DelRecording(recording);
}
@@ -397,23 +451,20 @@ string cHelpers::SetTimerIntern(char op, string param) {
return Error("Error in timer settings");
}
- cTimer* checkTimer = Timers.GetTimer(newTimer.get());
+ WRITE_LOCK_TIMERS;
+ cTimer* checkTimer = theTimers->GetTimer(newTimer.get());
if (checkTimer) {
return Error("Timer already defined");
}
- Timers.Add(newTimer.get());
- Timers.SetModified();
+ theTimers->Add(newTimer.get());
+ theTimers->SetModified();
dsyslog("[vdrmanager] timer %s added", *newTimer->ToDescr());
newTimer.release();
break;
}
case 'D':
case 'd': {
- if (Timers.BeingEdited()) {
- return Error("Timers are being edited - try again later");
- }
-
dsyslog("[vdrmanager] try parse %s ", param.c_str());
auto_ptr<cTimer> timer(new cTimer);
@@ -423,7 +474,8 @@ string cHelpers::SetTimerIntern(char op, string param) {
dsyslog("[vdrmanager] timer %s parsed", *timer->ToDescr());
- cTimer * t = Timers.GetTimer(timer.get());
+ WRITE_LOCK_TIMERS;
+ cTimer * t = theTimers->GetTimer(timer.get());
if (!t) {
return Error("Timer not defined");
@@ -437,24 +489,20 @@ string cHelpers::SetTimerIntern(char op, string param) {
if (t->Recording()) {
if (forceDelete == true) {
t->Skip();
- cRecordControls::Process(time(NULL));
+ RECORDING_CONTROLS_PROCESS;
} else {
return Error("Timer is recording");
}
}
dsyslog("[vdrmanager] deleting timer %s", *t->ToDescr());
- Timers.Del(t);
- Timers.SetModified();
+ theTimers->Del(t);
+ theTimers->SetModified();
break;
}
case 'M':
case 'm': {
- if (Timers.BeingEdited()) {
- return Error("Timers are being edited - try again later");
- }
-
string sep = string(TIMER_SEP);
size_t idx = param.find(sep);
@@ -470,7 +518,8 @@ string cHelpers::SetTimerIntern(char op, string param) {
return Error("Error in timer settings");
}
- cTimer* oldTimer = Timers.GetTimer(otimer.get());
+ WRITE_LOCK_TIMERS;
+ cTimer* oldTimer = theTimers->GetTimer(otimer.get());
if (oldTimer == 0) {
return Error("Timer not defined");
}
@@ -481,7 +530,7 @@ string cHelpers::SetTimerIntern(char op, string param) {
}
*oldTimer = copy;
- Timers.SetModified();
+ theTimers->SetModified();
dsyslog("[vdrmanager] timer %s modified (%s)", *oldTimer->ToDescr(),
oldTimer->HasFlags(tfActive) ? "active" : "inactive");
@@ -489,22 +538,19 @@ string cHelpers::SetTimerIntern(char op, string param) {
}
case 'T':
case 't': {
- if (Timers.BeingEdited()) {
- return Error("Timers are being edited - try again later");
- }
-
auto_ptr<cTimer> timer(new cTimer);
if (!timer->Parse(param.c_str())) {
return Error("Error in timer settings");
}
- cTimer* toggleTimer = Timers.GetTimer(timer.get());
+ WRITE_LOCK_TIMERS;
+ cTimer* toggleTimer = theTimers->GetTimer(timer.get());
if (toggleTimer == 0) {
return Error("Timer not defined");
}
toggleTimer->OnOff();
- Timers.SetModified();
+ theTimers->SetModified();
dsyslog("[vdrmanager] timer %s toggled %s", *toggleTimer->ToDescr(),
toggleTimer->HasFlags(tfActive) ? "on" : "off");
break;
@@ -524,10 +570,6 @@ string cHelpers::SetTimerIntern(string args) {
//return "!ERROR:no separator found\r\n";
//}
- if (Timers.BeingEdited()) {
- return Error("Timers are being edited - try again later");
- }
-
char operation = args[0];
args = Trim(args.substr(1));
@@ -557,18 +599,18 @@ string cHelpers::SearchEventsIntern(string wantedChannels, string pattern) {
string result = "START\r\n";
- cSchedulesLock schedulesLock;
- const cSchedules * schedules = cSchedules::Schedules(schedulesLock);
- for (cSchedule * schedule = schedules->First(); schedule; schedule =
- schedules->Next(schedule)) {
+ READ_LOCK_SCHEDULES;
+ READ_LOCK_CHANNELS;
+ for (const cSchedule * schedule = theSchedules->First(); schedule; schedule =
+ theSchedules->Next(schedule)) {
- cChannel * channel = Channels.GetByChannelID(schedule->ChannelID());
+ const cChannel * channel = theChannels->GetByChannelID(schedule->ChannelID());
if (!IsWantedChannel(channel, wantedChannels)) {
continue;
}
const cList<cEvent> * events = schedule->Events();
- for (cEvent * event = events->First(); event;
+ for (const cEvent * event = events->First(); event;
event = events->Next(event)) {
if (IsWantedTime(0, event) && IsWantedEvent(event, pattern)) { //time must be ok, so stop > now
@@ -582,7 +624,7 @@ string cHelpers::SearchEventsIntern(string wantedChannels, string pattern) {
//copied from vdr-live
-long cHelpers::Duration(cRecording* recording) {
+long cHelpers::Duration(const cRecording* recording) {
long RecLength = 0;
if (!recording->FileName())
return 0;
@@ -623,7 +665,7 @@ long cHelpers::Duration(cRecording* recording) {
return RecLength;
}
-string cHelpers::ToText(cRecording * recording) {
+string cHelpers::ToText(const cRecording * recording) {
const cRecordingInfo * info = recording->Info();
#if APIVERSNUM >= 10705
const cEvent * event = info->GetEvent();
@@ -755,7 +797,7 @@ string cHelpers::ToText(cRecording * recording) {
return result;
}
-string cHelpers::ToText(cTimer * timer, set<string> conflicts) {
+string cHelpers::ToText(const cTimer * timer, set<string> conflicts) {
const cChannel * channel = timer->Channel();
const char * channelName = channel->Name();
@@ -808,16 +850,16 @@ string cHelpers::ToText(cTimer * timer, set<string> conflicts) {
const cEvent * event = timer->Event();
if (!event) {
dsyslog("[vdrmanager] timer's event is NULL. Try find it");
- cChannel * channel = Channels.GetByChannelID(
+ READ_LOCK_CHANNELS;
+ const cChannel * channel = theChannels->GetByChannelID(
timer->Channel()->GetChannelID());
if (channel) {
- cSchedulesLock schedulesLock;
- const cSchedules * schedules = cSchedules::Schedules(schedulesLock);
- const cSchedule * schedule = schedules->GetSchedule(
+ READ_LOCK_SCHEDULES;
+ const cSchedule * schedule = theSchedules->GetSchedule(
channel->GetChannelID());
if (schedule) {
const cList<cEvent> * events = schedule->Events();
- for (cEvent * ev = events->First(); event;
+ for (const cEvent * ev = events->First(); event;
ev = events->Next(ev)) {
if (timer->StartTime() <= ev->StartTime()
&& timer->StopTime()
@@ -873,7 +915,8 @@ string cHelpers::ToText(cTimer * timer, set<string> conflicts) {
string cHelpers::ToText(const cEvent * event) {
- cChannel * channel = Channels.GetByChannelID(
+ READ_LOCK_CHANNELS;
+ LIST_ELEM_CONST cChannel * channel = theChannels->GetByChannelID(
event->Schedule()->ChannelID());
// search assigned timer
@@ -936,7 +979,8 @@ string cHelpers::ToText(const cEvent * event) {
result += "\r\n";
- cTimer * eventTimer = Timers.GetMatch(event);
+ READ_LOCK_TIMERS;
+ LIST_ELEM_CONST cTimer * eventTimer = theTimers->GetMatch(event);
if (eventTimer) {
result += ToText(eventTimer, set<string>());
@@ -945,7 +989,7 @@ string cHelpers::ToText(const cEvent * event) {
return result;
}
-bool cHelpers::IsWantedEvent(cEvent * event, string pattern) {
+bool cHelpers::IsWantedEvent(const cEvent * event, string pattern) {
string text = event->Title();
if (event->Description()) {
@@ -955,7 +999,7 @@ bool cHelpers::IsWantedEvent(cEvent * event, string pattern) {
return ToLower(text).find(ToLower(pattern)) != string::npos;
}
-bool cHelpers::IsWantedChannel(cChannel * channel, string wantedChannels) {
+bool cHelpers::IsWantedChannel(const cChannel * channel, string wantedChannels) {
if (!channel) {
return false;
@@ -998,7 +1042,7 @@ bool cHelpers::IsWantedChannel(cChannel * channel, string wantedChannels) {
return found;
}
-bool cHelpers::IsWantedTime(time_t when, cEvent * event) {
+bool cHelpers::IsWantedTime(time_t when, const cEvent * event) {
time_t startTime = event->StartTime();
time_t stopTime = startTime + event->Duration();
@@ -1142,7 +1186,7 @@ string cHelpers::UnMapSpecialChars(string text) {
/**
* based on vdr-restfulapi's RecordingLengthInSeconds
*/
-int cHelpers::RecordingLengthInSeconds(cRecording* recording) {
+int cHelpers::RecordingLengthInSeconds(const cRecording* recording) {
return Duration(recording) * 60;
}
diff --git a/vdr-vdrmanager/helpers.h b/vdr-vdrmanager/helpers.h
index d6e2a14..75701d7 100644
--- a/vdr-vdrmanager/helpers.h
+++ b/vdr-vdrmanager/helpers.h
@@ -32,7 +32,7 @@ public:
static string ToUpper(string text);
static string ToLower(string text);
static string Trim(string text);
- static long Duration(cRecording* recording);
+ static long Duration(const cRecording* recording);
private:
static string SafeCall(string (*)());
static string SafeCall(string (*)(string), string arg);
@@ -45,21 +45,21 @@ private:
static string DelRecordingIntern(string index);
static string SetTimerIntern(string args);
static string SearchEventsIntern(string wantedChannels, string pattern);
- static bool IsWantedEvent(cEvent * event, string pattern);
- static bool IsWantedChannel(cChannel * channel, string wantedChannels);
- static bool IsWantedTime(time_t when, cEvent * event);
+ static bool IsWantedEvent(const cEvent * event, string pattern);
+ static bool IsWantedChannel(const cChannel * channel, string wantedChannels);
+ static bool IsWantedTime(time_t when, const cEvent * event);
static string MapSpecialChars(const char * text);
static string MapSpecialChars(const cString text);
static string MapSpecialChars(const string text);
static string ToText(const cEvent * event);
- static string ToText(cTimer * timer, set<string> conflicts);
- static string ToText(cRecording * recording);
+ static string ToText(const cTimer * timer, set<string> conflicts);
+ static string ToText(const cRecording * recording);
static string GetAudioTracks(const cChannel* channel);
static string replaceAll(const string& where, const string& what, const string& replacement);
static string UnMapSpecialChars(string text);
static string Error(const string &error);
static string SetTimerIntern(char c, string params);
- static int RecordingLengthInSeconds(cRecording* recording);
+ static int RecordingLengthInSeconds(const cRecording* recording);
static string ConvertWeekdays(int v);
static int ConvertWeekdays(string v);
static queue<int> ConvertToBinary(int v);