Assigning events to timers no longer triggers sending a POLL to all peer VDRs

This commit is contained in:
Klaus Schmidinger 2018-03-04 14:15:07 +01:00
parent 75648e80cf
commit 1f9832b449
6 changed files with 42 additions and 30 deletions

View File

@ -9295,3 +9295,4 @@ Video Disk Recorder Revision History
in tools.c. in tools.c.
- Modified cStateLock's SetExplicitModify() and IncState() (changed to SetModified()) to - Modified cStateLock's SetExplicitModify() and IncState() (changed to SetModified()) to
allow for the introduction of syncing a separate cStateKey to a cStateLock. allow for the introduction of syncing a separate cStateKey to a cStateLock.
- Assigning events to timers no longer triggers sending a POLL to all peer VDRs.

21
svdrp.c
View File

@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured * and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection. * graphical interface that sits on top of an SVDRP connection.
* *
* $Id: svdrp.c 4.32 2018/03/01 14:45:57 kls Exp $ * $Id: svdrp.c 4.33 2018/03/04 14:15:07 kls Exp $
*/ */
#include "svdrp.h" #include "svdrp.h"
@ -37,7 +37,6 @@
#include "recording.h" #include "recording.h"
#include "remote.h" #include "remote.h"
#include "skins.h" #include "skins.h"
#include "thread.h"
#include "timers.h" #include "timers.h"
#include "videodir.h" #include "videodir.h"
@ -568,12 +567,13 @@ cSVDRPServerParams::cSVDRPServerParams(const char *Params)
// --- cSVDRPClientHandler --------------------------------------------------- // --- cSVDRPClientHandler ---------------------------------------------------
cStateKey StateKeySVDRPRemoteTimersPoll(true);
class cSVDRPClientHandler : public cThread { class cSVDRPClientHandler : public cThread {
private: private:
cMutex mutex; cMutex mutex;
int tcpPort; int tcpPort;
cSocket udpSocket; cSocket udpSocket;
cStateKey timersStateKey;
cVector<cSVDRPClient *> clientConnections; cVector<cSVDRPClient *> clientConnections;
void SendDiscover(void); void SendDiscover(void);
void HandleClientConnection(void); void HandleClientConnection(void);
@ -597,7 +597,6 @@ static cSVDRPClientHandler *SVDRPClientHandler = NULL;
cSVDRPClientHandler::cSVDRPClientHandler(int TcpPort, int UdpPort) cSVDRPClientHandler::cSVDRPClientHandler(int TcpPort, int UdpPort)
:cThread("SVDRP client handler", true) :cThread("SVDRP client handler", true)
,udpSocket(UdpPort, false) ,udpSocket(UdpPort, false)
,timersStateKey(true)
{ {
tcpPort = TcpPort; tcpPort = TcpPort;
} }
@ -627,11 +626,11 @@ void cSVDRPClientHandler::SendDiscover(void)
void cSVDRPClientHandler::ProcessConnections(void) void cSVDRPClientHandler::ProcessConnections(void)
{ {
cString PollTimersCmd; cString PollTimersCmd;
if (cTimers::GetTimersRead(timersStateKey, 100)) { if (cTimers::GetTimersRead(StateKeySVDRPRemoteTimersPoll, 100)) {
PollTimersCmd = cString::sprintf("POLL %s TIMERS", Setup.SVDRPHostName); PollTimersCmd = cString::sprintf("POLL %s TIMERS", Setup.SVDRPHostName);
timersStateKey.Remove(); StateKeySVDRPRemoteTimersPoll.Remove();
} }
else if (timersStateKey.TimedOut()) else if (StateKeySVDRPRemoteTimersPoll.TimedOut())
return; // try again next time return; // try again next time
for (int i = 0; i < clientConnections.Size(); i++) { for (int i = 0; i < clientConnections.Size(); i++) {
cSVDRPClient *Client = clientConnections[i]; cSVDRPClient *Client = clientConnections[i];
@ -639,9 +638,9 @@ void cSVDRPClientHandler::ProcessConnections(void)
if (Client->HasFetchFlag(sffTimers)) { if (Client->HasFetchFlag(sffTimers)) {
cStringList RemoteTimers; cStringList RemoteTimers;
if (Client->GetRemoteTimers(RemoteTimers)) { if (Client->GetRemoteTimers(RemoteTimers)) {
if (cTimers *Timers = cTimers::GetTimersWrite(timersStateKey, 100)) { if (cTimers *Timers = cTimers::GetTimersWrite(StateKeySVDRPRemoteTimersPoll, 100)) {
bool TimersModified = Timers->StoreRemoteTimers(Client->ServerName(), &RemoteTimers); bool TimersModified = Timers->StoreRemoteTimers(Client->ServerName(), &RemoteTimers);
timersStateKey.Remove(TimersModified); StateKeySVDRPRemoteTimersPoll.Remove(TimersModified);
} }
else else
Client->SetFetchFlag(sffTimers); // try again next time Client->SetFetchFlag(sffTimers); // try again next time
@ -653,9 +652,9 @@ void cSVDRPClientHandler::ProcessConnections(void)
} }
} }
else { else {
cTimers *Timers = cTimers::GetTimersWrite(timersStateKey); cTimers *Timers = cTimers::GetTimersWrite(StateKeySVDRPRemoteTimersPoll);
bool TimersModified = Timers->StoreRemoteTimers(Client->ServerName(), NULL); bool TimersModified = Timers->StoreRemoteTimers(Client->ServerName(), NULL);
timersStateKey.Remove(TimersModified); StateKeySVDRPRemoteTimersPoll.Remove(TimersModified);
delete Client; delete Client;
clientConnections.Remove(i); clientConnections.Remove(i);
i--; i--;

View File

@ -4,12 +4,13 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: svdrp.h 4.9 2018/02/25 13:38:59 kls Exp $ * $Id: svdrp.h 4.10 2018/03/04 12:26:17 kls Exp $
*/ */
#ifndef __SVDRP_H #ifndef __SVDRP_H
#define __SVDRP_H #define __SVDRP_H
#include "thread.h"
#include "tools.h" #include "tools.h"
enum eSvdrpPeerModes { enum eSvdrpPeerModes {
@ -23,6 +24,10 @@ enum eSvdrpFetchFlags {
sffTimers = 0b0001, sffTimers = 0b0001,
}; };
extern cStateKey StateKeySVDRPRemoteTimersPoll;
///< Controls whether a change to the local list of timers needs to result in
///< sending a POLL to the remote clients.
void SetSVDRPPorts(int TcpPort, int UdpPort); void SetSVDRPPorts(int TcpPort, int UdpPort);
void SetSVDRPGrabImageDir(const char *GrabImageDir); void SetSVDRPGrabImageDir(const char *GrabImageDir);
void StartSVDRPHandler(void); void StartSVDRPHandler(void);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: thread.c 4.12 2018/03/04 11:23:09 kls Exp $ * $Id: thread.c 4.13 2018/03/04 13:17:04 kls Exp $
*/ */
#include "thread.h" #include "thread.h"
@ -877,7 +877,6 @@ bool cStateKey::StateChanged(void)
return state != stateLock->state; return state != stateLock->state;
else else
return true; return true;
return false;
} }
// --- cIoThrottle ----------------------------------------------------------- // --- cIoThrottle -----------------------------------------------------------

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: tools.h 4.15 2018/02/28 10:13:40 kls Exp $ * $Id: tools.h 4.16 2018/03/04 14:06:36 kls Exp $
*/ */
#ifndef __TOOLS_H #ifndef __TOOLS_H
@ -559,6 +559,11 @@ public:
///< Contains() function to check whether an object you are holding a pointer ///< Contains() function to check whether an object you are holding a pointer
///< to is still in the list. Note that the garbage collector is purged when ///< to is still in the list. Note that the garbage collector is purged when
///< the usual housekeeping is done. ///< the usual housekeeping is done.
void SetSyncStateKey(cStateKey &StateKey) { stateLock.SetSyncStateKey(StateKey); }
///< When making changes to this list (while holding a write lock) that shall
///< not affect some other code that reacts to such changes, this function can
///< be called with the StateKey used by that other code.
///< See cStateLock::SetSyncStateKey() for details.
void SetUseGarbageCollector(void) { useGarbageCollector = true; } void SetUseGarbageCollector(void) { useGarbageCollector = true; }
void SetExplicitModify(void); void SetExplicitModify(void);
///< If you have obtained a write lock on this list, and you don't want it to ///< If you have obtained a write lock on this list, and you don't want it to

33
vdr.c
View File

@ -22,7 +22,7 @@
* *
* The project's page is at http://www.tvdr.de * The project's page is at http://www.tvdr.de
* *
* $Id: vdr.c 4.23 2018/02/25 13:45:24 kls Exp $ * $Id: vdr.c 4.24 2018/03/04 14:00:29 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
@ -1078,25 +1078,28 @@ int main(int argc, char *argv[])
PreviousChannel[PreviousChannelIndex ^= 1] = LastChannel; PreviousChannel[PreviousChannelIndex ^= 1] = LastChannel;
{ {
// Timers and Recordings: // Timers and Recordings:
bool TimersModified = false; static cStateKey TimersStateKey;
static cStateKey TimersStateKey(true);
if (cTimers::GetTimersRead(TimersStateKey))
TimersStateKey.Remove();
cTimers *Timers = cTimers::GetTimersWrite(TimersStateKey); cTimers *Timers = cTimers::GetTimersWrite(TimersStateKey);
// Assign events to timers: {
static cStateKey SchedulesStateKey; // Assign events to timers:
if (const cSchedules *Schedules = cSchedules::GetSchedulesRead(SchedulesStateKey)) static cStateKey SchedulesStateKey;
TimersModified |= Timers->SetEvents(Schedules); if (TimersStateKey.StateChanged())
SchedulesStateKey.Reset(); // we assign events if either the Timers or the Schedules have changed
bool TimersModified = false;
if (const cSchedules *Schedules = cSchedules::GetSchedulesRead(SchedulesStateKey)) {
Timers->SetSyncStateKey(StateKeySVDRPRemoteTimersPoll);
if (Timers->SetEvents(Schedules))
TimersModified = true;
SchedulesStateKey.Remove();
}
TimersStateKey.Remove(TimersModified); // we need to remove the key here, so that syncing StateKeySVDRPRemoteTimersPoll takes effect!
}
// Must do all following calls with the exact same time! // Must do all following calls with the exact same time!
// Process ongoing recordings: // Process ongoing recordings:
Timers = cTimers::GetTimersWrite(TimersStateKey);
bool TimersModified = false;
if (cRecordControls::Process(Timers, Now)) if (cRecordControls::Process(Timers, Now))
TimersModified = true; TimersModified = true;
// Must keep the lock on the schedules until after processing the record
// controls, in order to avoid short interrupts in case the current event
// is replaced by a new one (which some broadcasters do, instead of just
// modifying the current event's data):
if (SchedulesStateKey.InLock())
SchedulesStateKey.Remove();
// Start new recordings: // Start new recordings:
if (cTimer *Timer = Timers->GetMatch(Now)) { if (cTimer *Timer = Timers->GetMatch(Now)) {
if (!cRecordControls::Start(Timers, Timer)) if (!cRecordControls::Start(Timers, Timer))