mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Moved handling remote timers into cSVDRPClientHandler::ProcessConnections()
This commit is contained in:
		
							
								
								
									
										3
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								HISTORY
									
									
									
									
									
								
							@@ -9162,7 +9162,7 @@ Video Disk Recorder Revision History
 | 
			
		||||
  a subdirectory.
 | 
			
		||||
- SVDRP peering can now be limited to the default SVDRP host (see MANUAL for details).
 | 
			
		||||
 | 
			
		||||
2018-02-20: Version 2.3.9
 | 
			
		||||
2018-02-25: Version 2.3.9
 | 
			
		||||
 | 
			
		||||
- Updated the Italian OSD texts (thanks to Diego Pierotto).
 | 
			
		||||
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
 | 
			
		||||
@@ -9283,3 +9283,4 @@ Video Disk Recorder Revision History
 | 
			
		||||
  SVDRP command CONN instead of using the UDP port with the server's address.
 | 
			
		||||
  This change requires that all VDRs that shall take part in a peer-to-peer network need
 | 
			
		||||
  to be updated to this version.
 | 
			
		||||
- Moved handling remote timers into cSVDRPClientHandler::ProcessConnections().
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								menu.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: menu.c 4.61 2018/02/13 09:25:43 kls Exp $
 | 
			
		||||
 * $Id: menu.c 4.62 2018/02/25 13:07:09 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "menu.h"
 | 
			
		||||
@@ -4184,7 +4184,7 @@ eOSState cMenuSetupMisc::ProcessKey(eKeys Key)
 | 
			
		||||
     else {
 | 
			
		||||
        LOCK_TIMERS_WRITE;
 | 
			
		||||
        Timers->SetExplicitModify();
 | 
			
		||||
        if (Timers->DelRemoteTimers())
 | 
			
		||||
        if (Timers->StoreRemoteTimers(NULL, NULL))
 | 
			
		||||
           Timers->SetModified();
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										72
									
								
								svdrp.c
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								svdrp.c
									
									
									
									
									
								
							@@ -10,7 +10,7 @@
 | 
			
		||||
 * and interact with the Video Disk Recorder - or write a full featured
 | 
			
		||||
 * graphical interface that sits on top of an SVDRP connection.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: svdrp.c 4.27 2018/02/20 13:28:04 kls Exp $
 | 
			
		||||
 * $Id: svdrp.c 4.28 2018/02/25 13:26:17 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "svdrp.h"
 | 
			
		||||
@@ -317,6 +317,7 @@ private:
 | 
			
		||||
  cFile file;
 | 
			
		||||
  int fetchFlags;
 | 
			
		||||
  bool connected;
 | 
			
		||||
  bool Send(const char *Command);
 | 
			
		||||
  void Close(void);
 | 
			
		||||
public:
 | 
			
		||||
  cSVDRPClient(const char *Address, int Port, const char *ServerName, int Timeout);
 | 
			
		||||
@@ -324,12 +325,12 @@ public:
 | 
			
		||||
  const char *ServerName(void) const { return serverName; }
 | 
			
		||||
  const char *Connection(void) const { return serverIpAddress.Connection(); }
 | 
			
		||||
  bool HasAddress(const char *Address, int Port) const;
 | 
			
		||||
  bool Send(const char *Command);
 | 
			
		||||
  bool Process(cStringList *Response = NULL);
 | 
			
		||||
  bool Execute(const char *Command, cStringList *Response = NULL);
 | 
			
		||||
  bool Connected(void) const { return connected; }
 | 
			
		||||
  void SetFetchFlag(eSvdrpFetchFlags Flag);
 | 
			
		||||
  bool HasFetchFlag(eSvdrpFetchFlags Flag);
 | 
			
		||||
  bool GetRemoteTimers(cStringList &Response);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
static cPoller SVDRPClientPoller;
 | 
			
		||||
@@ -365,9 +366,6 @@ void cSVDRPClient::Close(void)
 | 
			
		||||
     SVDRPClientPoller.Del(file, false);
 | 
			
		||||
     file.Close();
 | 
			
		||||
     socket.Close();
 | 
			
		||||
     LOCK_TIMERS_WRITE;
 | 
			
		||||
     if (Timers)
 | 
			
		||||
        Timers->DelRemoteTimers(serverName);
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -483,6 +481,14 @@ bool cSVDRPClient::HasFetchFlag(eSvdrpFetchFlags Flag)
 | 
			
		||||
  return Result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cSVDRPClient::GetRemoteTimers(cStringList &Response)
 | 
			
		||||
{
 | 
			
		||||
  if (HasFetchFlag(sffTimers))
 | 
			
		||||
     return Execute("LSTT ID", &Response);
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// --- cSVDRPServerParams ----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
class cSVDRPServerParams {
 | 
			
		||||
@@ -554,20 +560,21 @@ private:
 | 
			
		||||
  cMutex mutex;
 | 
			
		||||
  int tcpPort;
 | 
			
		||||
  cSocket udpSocket;
 | 
			
		||||
  cStateKey timersStateKey;
 | 
			
		||||
  cVector<cSVDRPClient *> clientConnections;
 | 
			
		||||
  void SendDiscover(void);
 | 
			
		||||
  void HandleClientConnection(void);
 | 
			
		||||
  void ProcessConnections(void);
 | 
			
		||||
  cSVDRPClient *GetClientForServer(const char *ServerName);
 | 
			
		||||
protected:
 | 
			
		||||
  virtual void Action(void);
 | 
			
		||||
public:
 | 
			
		||||
  cSVDRPClientHandler(int TcpPort, int UdpPort);
 | 
			
		||||
  virtual ~cSVDRPClientHandler();
 | 
			
		||||
  void SendDiscover(void);
 | 
			
		||||
  void AddClient(cSVDRPServerParams &ServerParams, const char *IpAddress);
 | 
			
		||||
  bool Execute(const char *ServerName, const char *Command, cStringList *Response = NULL);
 | 
			
		||||
  bool GetServerNames(cStringList *ServerNames, eSvdrpFetchFlags FetchFlags = sffNone);
 | 
			
		||||
  bool TriggerFetchingTimers(const char *ServerName);
 | 
			
		||||
  cSVDRPClient *GetClientForServer(const char *ServerName);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
static cSVDRPClientHandler *SVDRPClientHandler = NULL;
 | 
			
		||||
@@ -575,6 +582,7 @@ static cSVDRPClientHandler *SVDRPClientHandler = NULL;
 | 
			
		||||
cSVDRPClientHandler::cSVDRPClientHandler(int TcpPort, int UdpPort)
 | 
			
		||||
:cThread("SVDRP client handler", true)
 | 
			
		||||
,udpSocket(UdpPort, false)
 | 
			
		||||
,timersStateKey(true)
 | 
			
		||||
{
 | 
			
		||||
  tcpPort = TcpPort;
 | 
			
		||||
}
 | 
			
		||||
@@ -588,7 +596,6 @@ cSVDRPClientHandler::~cSVDRPClientHandler()
 | 
			
		||||
 | 
			
		||||
cSVDRPClient *cSVDRPClientHandler::GetClientForServer(const char *ServerName)
 | 
			
		||||
{
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  for (int i = 0; i < clientConnections.Size(); i++) {
 | 
			
		||||
      if (strcmp(clientConnections[i]->ServerName(), ServerName) == 0)
 | 
			
		||||
         return clientConnections[i];
 | 
			
		||||
@@ -598,17 +605,36 @@ cSVDRPClient *cSVDRPClientHandler::GetClientForServer(const char *ServerName)
 | 
			
		||||
 | 
			
		||||
void cSVDRPClientHandler::SendDiscover(void)
 | 
			
		||||
{
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  cString Dgram = cString::sprintf("SVDRP:discover name:%s port:%d vdrversion:%d apiversion:%d timeout:%d%s", Setup.SVDRPHostName, tcpPort, VDRVERSNUM, APIVERSNUM, Setup.SVDRPTimeout, (Setup.SVDRPPeering == spmOnly && *Setup.SVDRPDefaultHost) ? *cString::sprintf(" host:%s", Setup.SVDRPDefaultHost) : "");
 | 
			
		||||
  udpSocket.SendDgram(Dgram, udpSocket.Port());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cSVDRPClientHandler::ProcessConnections(void)
 | 
			
		||||
{
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  cString PollTimersCmd;
 | 
			
		||||
  if (cTimers::GetTimersRead(timersStateKey)) {
 | 
			
		||||
     PollTimersCmd = cString::sprintf("POLL %s TIMERS", Setup.SVDRPHostName);
 | 
			
		||||
     timersStateKey.Remove();
 | 
			
		||||
     }
 | 
			
		||||
  for (int i = 0; i < clientConnections.Size(); i++) {
 | 
			
		||||
      if (!clientConnections[i]->Process()) {
 | 
			
		||||
         delete clientConnections[i];
 | 
			
		||||
      cSVDRPClient *Client = clientConnections[i];
 | 
			
		||||
      if (Client->Process()) {
 | 
			
		||||
         cStringList RemoteTimers;
 | 
			
		||||
         if (Client->GetRemoteTimers(RemoteTimers)) {
 | 
			
		||||
            cTimers *Timers = cTimers::GetTimersWrite(timersStateKey);
 | 
			
		||||
            bool TimersModified = Timers->StoreRemoteTimers(Client->ServerName(), &RemoteTimers);
 | 
			
		||||
            timersStateKey.Remove(TimersModified);
 | 
			
		||||
            }
 | 
			
		||||
         if (*PollTimersCmd) {
 | 
			
		||||
            if (!Client->Execute(PollTimersCmd))
 | 
			
		||||
               esyslog("ERROR: can't send '%s' to '%s'", *PollTimersCmd, Client->ServerName());
 | 
			
		||||
            }
 | 
			
		||||
         }
 | 
			
		||||
      else {
 | 
			
		||||
         cTimers *Timers = cTimers::GetTimersWrite(timersStateKey);
 | 
			
		||||
         bool TimersModified = Timers->StoreRemoteTimers(Client->ServerName(), NULL);
 | 
			
		||||
         timersStateKey.Remove(TimersModified);
 | 
			
		||||
         delete Client;
 | 
			
		||||
         clientConnections.Remove(i);
 | 
			
		||||
         i--;
 | 
			
		||||
         }
 | 
			
		||||
@@ -617,11 +643,10 @@ void cSVDRPClientHandler::ProcessConnections(void)
 | 
			
		||||
 | 
			
		||||
void cSVDRPClientHandler::AddClient(cSVDRPServerParams &ServerParams, const char *IpAddress)
 | 
			
		||||
{
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  for (int i = 0; i < clientConnections.Size(); i++) {
 | 
			
		||||
      if (clientConnections[i]->HasAddress(IpAddress, ServerParams.Port())) {
 | 
			
		||||
         dsyslog("SVDRP %s < %s connection to '%s' already exists", Setup.SVDRPHostName, clientConnections[i]->Connection(), clientConnections[i]->ServerName());
 | 
			
		||||
      if (clientConnections[i]->HasAddress(IpAddress, ServerParams.Port()))
 | 
			
		||||
         return;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
  if (Setup.SVDRPPeering == spmOnly && strcmp(ServerParams.Name(), Setup.SVDRPDefaultHost) != 0)
 | 
			
		||||
     return; // we only want to peer with the default host, but this isn't the default host
 | 
			
		||||
@@ -1294,8 +1319,7 @@ void cSVDRPServer::CmdCONN(const char *Option)
 | 
			
		||||
        if (ServerParams.Ok()) {
 | 
			
		||||
           clientName = ServerParams.Name();
 | 
			
		||||
           Reply(250, "OK"); // must finish this transaction before creating the new client
 | 
			
		||||
           if (!SVDRPClientHandler->GetClientForServer(ServerParams.Name()))
 | 
			
		||||
              SVDRPClientHandler->AddClient(ServerParams, clientIpAddress.Address());
 | 
			
		||||
           SVDRPClientHandler->AddClient(ServerParams, clientIpAddress.Address());
 | 
			
		||||
           }
 | 
			
		||||
        else
 | 
			
		||||
           Reply(501, "Error in server parameters: %s", ServerParams.Error());
 | 
			
		||||
@@ -2601,7 +2625,6 @@ void SetSVDRPGrabImageDir(const char *GrabImageDir)
 | 
			
		||||
 | 
			
		||||
class cSVDRPServerHandler : public cThread {
 | 
			
		||||
private:
 | 
			
		||||
  cMutex mutex;
 | 
			
		||||
  bool ready;
 | 
			
		||||
  cSocket tcpSocket;
 | 
			
		||||
  cVector<cSVDRPServer *> serverConnections;
 | 
			
		||||
@@ -2613,7 +2636,6 @@ public:
 | 
			
		||||
  cSVDRPServerHandler(int TcpPort);
 | 
			
		||||
  virtual ~cSVDRPServerHandler();
 | 
			
		||||
  void WaitUntilReady(void);
 | 
			
		||||
  cSVDRPServer *GetServerForClient(const char *ClientName);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
static cSVDRPServerHandler *SVDRPServerHandler = NULL;
 | 
			
		||||
@@ -2641,7 +2663,6 @@ void cSVDRPServerHandler::WaitUntilReady(void)
 | 
			
		||||
 | 
			
		||||
void cSVDRPServerHandler::ProcessConnections(void)
 | 
			
		||||
{
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  for (int i = 0; i < serverConnections.Size(); i++) {
 | 
			
		||||
      if (!serverConnections[i]->Process()) {
 | 
			
		||||
         delete serverConnections[i];
 | 
			
		||||
@@ -2665,7 +2686,6 @@ void cSVDRPServerHandler::Action(void)
 | 
			
		||||
     ready = true;
 | 
			
		||||
     while (Running()) {
 | 
			
		||||
           SVDRPServerPoller.Poll(1000);
 | 
			
		||||
           cMutexLock MutexLock(&mutex);
 | 
			
		||||
           HandleServerConnection();
 | 
			
		||||
           ProcessConnections();
 | 
			
		||||
           }
 | 
			
		||||
@@ -2674,16 +2694,6 @@ void cSVDRPServerHandler::Action(void)
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cSVDRPServer *cSVDRPServerHandler::GetServerForClient(const char *ClientName)
 | 
			
		||||
{
 | 
			
		||||
  cMutexLock MutexLock(&mutex);
 | 
			
		||||
  for (int i = 0; i < serverConnections.Size(); i++) {
 | 
			
		||||
      if (serverConnections[i]->ClientName() && strcmp(serverConnections[i]->ClientName(), ClientName) == 0)
 | 
			
		||||
         return serverConnections[i];
 | 
			
		||||
      }
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- SVDRP Handler ---------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
static cMutex SVDRPHandlerMutex;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										94
									
								
								timers.c
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								timers.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: timers.c 4.14 2017/11/12 13:01:22 kls Exp $
 | 
			
		||||
 * $Id: timers.c 4.15 2018/02/25 13:05:03 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
@@ -898,78 +898,48 @@ bool cTimers::DeleteExpired(void)
 | 
			
		||||
  return TimersModified;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cTimers::GetRemoteTimers(const char *ServerName)
 | 
			
		||||
bool cTimers::StoreRemoteTimers(const char *ServerName, const cStringList *RemoteTimers)
 | 
			
		||||
{
 | 
			
		||||
  //TODO handle only new/deleted/modified timers?
 | 
			
		||||
  bool Result = false;
 | 
			
		||||
  if (ServerName) {
 | 
			
		||||
     Result = DelRemoteTimers(ServerName);
 | 
			
		||||
     cStringList Response;
 | 
			
		||||
     if (ExecSVDRPCommand(ServerName, "LSTT ID", &Response)) {
 | 
			
		||||
        for (int i = 0; i < Response.Size(); i++) {
 | 
			
		||||
            const char *s = Response[i];
 | 
			
		||||
            int Code = SVDRPCode(s);
 | 
			
		||||
            if (Code == 250) {
 | 
			
		||||
               if (const char *v = SVDRPValue(s)) {
 | 
			
		||||
                  int Id = atoi(v);
 | 
			
		||||
                  while (*v && *v != ' ')
 | 
			
		||||
                        v++; // skip id
 | 
			
		||||
                  cTimer *Timer = new cTimer;
 | 
			
		||||
                  if (Timer->Parse(v)) {
 | 
			
		||||
                     Timer->SetRemote(ServerName);
 | 
			
		||||
                     Timer->SetId(Id);
 | 
			
		||||
                     Add(Timer);
 | 
			
		||||
                     Result = true;
 | 
			
		||||
                     }
 | 
			
		||||
                  else {
 | 
			
		||||
                     esyslog("ERROR: %s: error in timer settings: %s", ServerName, v);
 | 
			
		||||
                     delete Timer;
 | 
			
		||||
                     }
 | 
			
		||||
                  }
 | 
			
		||||
               }
 | 
			
		||||
            else if (Code != 550)
 | 
			
		||||
               esyslog("ERROR: %s: %s", ServerName, s);
 | 
			
		||||
            }
 | 
			
		||||
        return Result;
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  else {
 | 
			
		||||
     cStringList ServerNames;
 | 
			
		||||
     if (GetSVDRPServerNames(&ServerNames, sffTimers)) {
 | 
			
		||||
        for (int i = 0; i < ServerNames.Size(); i++)
 | 
			
		||||
            Result |= GetRemoteTimers(ServerNames[i]);
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  return Result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cTimers::DelRemoteTimers(const char *ServerName)
 | 
			
		||||
{
 | 
			
		||||
  bool Deleted = false;
 | 
			
		||||
  // Delete old remote timers:
 | 
			
		||||
  cTimer *Timer = First();
 | 
			
		||||
  while (Timer) {
 | 
			
		||||
        cTimer *t = Next(Timer);
 | 
			
		||||
        if (Timer->Remote() && (!ServerName || strcmp(Timer->Remote(), ServerName) == 0)) {
 | 
			
		||||
           Del(Timer);
 | 
			
		||||
           Deleted = true;
 | 
			
		||||
           Result = true;
 | 
			
		||||
           }
 | 
			
		||||
        Timer = t;
 | 
			
		||||
        }
 | 
			
		||||
  return Deleted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTimers::TriggerRemoteTimerPoll(const char *ServerName)
 | 
			
		||||
{
 | 
			
		||||
  if (ServerName) {
 | 
			
		||||
     if (!ExecSVDRPCommand(ServerName, cString::sprintf("POLL %s TIMERS", Setup.SVDRPHostName)))
 | 
			
		||||
        esyslog("ERROR: can't send 'POLL %s TIMERS' to '%s'", Setup.SVDRPHostName, ServerName);
 | 
			
		||||
     }
 | 
			
		||||
  else {
 | 
			
		||||
     cStringList ServerNames;
 | 
			
		||||
     if (GetSVDRPServerNames(&ServerNames)) {
 | 
			
		||||
        for (int i = 0; i < ServerNames.Size(); i++)
 | 
			
		||||
            TriggerRemoteTimerPoll(ServerNames[i]);
 | 
			
		||||
        }
 | 
			
		||||
  // Add new remote timers:
 | 
			
		||||
  if (ServerName && RemoteTimers) {
 | 
			
		||||
     for (int i = 0; i < RemoteTimers->Size(); i++) {
 | 
			
		||||
         const char *s = (*RemoteTimers)[i];
 | 
			
		||||
         int Code = SVDRPCode(s);
 | 
			
		||||
         if (Code == 250) {
 | 
			
		||||
            if (const char *v = SVDRPValue(s)) {
 | 
			
		||||
               int Id = atoi(v);
 | 
			
		||||
               while (*v && *v != ' ')
 | 
			
		||||
                     v++; // skip id
 | 
			
		||||
               cTimer *Timer = new cTimer;
 | 
			
		||||
               if (Timer->Parse(v)) {
 | 
			
		||||
                  Timer->SetRemote(ServerName);
 | 
			
		||||
                  Timer->SetId(Id);
 | 
			
		||||
                  Add(Timer);
 | 
			
		||||
                  Result = true;
 | 
			
		||||
                  }
 | 
			
		||||
               else {
 | 
			
		||||
                  esyslog("ERROR: %s: error in timer settings: %s", ServerName, v);
 | 
			
		||||
                  delete Timer;
 | 
			
		||||
                  }
 | 
			
		||||
               }
 | 
			
		||||
            }
 | 
			
		||||
         else if (Code != 550)
 | 
			
		||||
            esyslog("ERROR: %s: %s", ServerName, s);
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
  return Result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool RemoteTimerError(const cTimer *Timer, cString *Msg)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								timers.h
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								timers.h
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: timers.h 4.9 2017/10/31 09:47:14 kls Exp $
 | 
			
		||||
 * $Id: timers.h 4.10 2018/02/25 12:54:55 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __TIMERS_H
 | 
			
		||||
@@ -185,21 +185,12 @@ public:
 | 
			
		||||
  void Add(cTimer *Timer, cTimer *After = NULL);
 | 
			
		||||
  void Ins(cTimer *Timer, cTimer *Before = NULL);
 | 
			
		||||
  void Del(cTimer *Timer, bool DeleteObject = true);
 | 
			
		||||
  bool GetRemoteTimers(const char *ServerName = NULL);
 | 
			
		||||
      ///< Gets the timers from the given remote machine and adds them to this
 | 
			
		||||
      ///< list. If no ServerName is given, all timers from all known remote
 | 
			
		||||
      ///< machines will be fetched. This function calls DelRemoteTimers() with
 | 
			
		||||
      ///< the given ServerName first.
 | 
			
		||||
  bool StoreRemoteTimers(const char *ServerName = NULL, const cStringList *RemoteTimers = NULL);
 | 
			
		||||
      ///< Stores the given list of RemoteTimers, which come from the VDR ServerName, in
 | 
			
		||||
      ///< this list. If no ServerName is given, all remote timers from all peer machines
 | 
			
		||||
      ///< will be removed from this list. If no RemoteTimers are given, only the remote
 | 
			
		||||
      ///< timers from ServerName will be removed from this list.
 | 
			
		||||
      ///< Returns true if any remote timers have been added or deleted
 | 
			
		||||
  bool DelRemoteTimers(const char *ServerName = NULL);
 | 
			
		||||
      ///< Deletes all timers of the given remote machine from this list (leaves
 | 
			
		||||
      ///< them untouched on the remote machine). If no ServerName is given, the
 | 
			
		||||
      ///< timers of all remote machines will be deleted from the list.
 | 
			
		||||
      ///< Returns true if any remote timers have been deleted.
 | 
			
		||||
  void TriggerRemoteTimerPoll(const char *ServerName = NULL);
 | 
			
		||||
      ///< Sends an SVDRP POLL command to the given remote machine.
 | 
			
		||||
      ///< If no ServerName is given, the POLL command will be sent to all
 | 
			
		||||
      ///< known remote machines.
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
bool HandleRemoteTimerModifications(cTimer *NewTimer, cTimer *OldTimer = NULL, cString *Msg = NULL);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								vdr.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								vdr.c
									
									
									
									
									
								
							@@ -22,7 +22,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 * The project's page is at http://www.tvdr.de
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: vdr.c 4.21 2017/11/09 16:15:34 kls Exp $
 | 
			
		||||
 * $Id: vdr.c 4.22 2018/02/25 13:07:09 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
@@ -1081,25 +1081,18 @@ int main(int argc, char *argv[])
 | 
			
		||||
        {
 | 
			
		||||
          // Timers and Recordings:
 | 
			
		||||
          bool TimersModified = false;
 | 
			
		||||
          bool TriggerRemoteTimerPoll = false;
 | 
			
		||||
          static cStateKey TimersStateKey(true);
 | 
			
		||||
          if (cTimers::GetTimersRead(TimersStateKey)) {
 | 
			
		||||
             TriggerRemoteTimerPoll = true;
 | 
			
		||||
          if (cTimers::GetTimersRead(TimersStateKey))
 | 
			
		||||
             TimersStateKey.Remove();
 | 
			
		||||
             }
 | 
			
		||||
          cTimers *Timers = cTimers::GetTimersWrite(TimersStateKey);
 | 
			
		||||
          // Get remote timers:
 | 
			
		||||
          TimersModified |= Timers->GetRemoteTimers();
 | 
			
		||||
          // Assign events to timers:
 | 
			
		||||
          static cStateKey SchedulesStateKey;
 | 
			
		||||
          if (const cSchedules *Schedules = cSchedules::GetSchedulesRead(SchedulesStateKey))
 | 
			
		||||
             TimersModified |= Timers->SetEvents(Schedules);
 | 
			
		||||
          // Must do all following calls with the exact same time!
 | 
			
		||||
          // Process ongoing recordings:
 | 
			
		||||
          if (cRecordControls::Process(Timers, Now)) {
 | 
			
		||||
          if (cRecordControls::Process(Timers, Now))
 | 
			
		||||
             TimersModified = true;
 | 
			
		||||
             TriggerRemoteTimerPoll = 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
 | 
			
		||||
@@ -1113,7 +1106,6 @@ int main(int argc, char *argv[])
 | 
			
		||||
             else
 | 
			
		||||
                LastTimerChannel = Timer->Channel()->Number();
 | 
			
		||||
             TimersModified = true;
 | 
			
		||||
             TriggerRemoteTimerPoll = true;
 | 
			
		||||
             }
 | 
			
		||||
          // Make sure timers "see" their channel early enough:
 | 
			
		||||
          static time_t LastTimerCheck = 0;
 | 
			
		||||
@@ -1168,13 +1160,8 @@ int main(int argc, char *argv[])
 | 
			
		||||
             LastTimerCheck = Now;
 | 
			
		||||
             }
 | 
			
		||||
          // Delete expired timers:
 | 
			
		||||
          if (Timers->DeleteExpired()) {
 | 
			
		||||
          if (Timers->DeleteExpired())
 | 
			
		||||
             TimersModified = true;
 | 
			
		||||
             TriggerRemoteTimerPoll = true;
 | 
			
		||||
             }
 | 
			
		||||
          // Trigger remote timer polls:
 | 
			
		||||
          if (TriggerRemoteTimerPoll)
 | 
			
		||||
             Timers->TriggerRemoteTimerPoll();
 | 
			
		||||
          // Make sure there is enough free disk space for ongoing recordings:
 | 
			
		||||
          AssertFreeDiskSpace(Timers->GetMaxPriority());
 | 
			
		||||
          TimersStateKey.Remove(TimersModified);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user