]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Started work on the client side timeouts
authorChris Tallon <chris@vomp.tv>
Sun, 11 May 2008 16:53:16 +0000 (16:53 +0000)
committerChris Tallon <chris@vomp.tv>
Sun, 11 May 2008 16:53:16 +0000 (16:53 +0000)
command.cc
playerliveradio.cc
playerlivetv.cc
vdr.cc

index 16fa00a0d49cceb0d598e01024d01dd5018fc93a..a2b1968741cd6bce33140c5c41707cf8a7cf0655 100644 (file)
@@ -569,7 +569,7 @@ void Command::connectionLost()
   Message* m = new Message(); // break into master mutex
   m->message = Message::CONNECTION_LOST;
   m->to = this;
-  postMessageNoLock(m);
+  postMessageFromOuterSpace(m);
 }
 
 void Command::buildCrashedBox()
index 5e798ae7577a138c70eb57ac9acd35c285acbe2e..e4a5f38c585e0af6d921723bc845563a4b0cf32b 100644 (file)
@@ -153,6 +153,7 @@ void PlayerLiveRadio::streamReceive(ULONG flag, void* data, ULONG len)
   // Flag:
   // 0 = normal stream packet
   // 1 = stream end
+  // 2 = connection lost
 
   if (flag == 1)
   {
index d0591ea331406fd37a9aee1db25a99f53a922f5d..6295ee90d6410c4cb133bec3398b054e19327c25 100644 (file)
@@ -215,6 +215,7 @@ void PlayerLiveTV::streamReceive(ULONG flag, void* data, ULONG len)
   // Flag:
   // 0 = normal stream packet
   // 1 = stream end
+  // 2 = connection lost
 
 //  logger->log("PlayerLiveTV", Log::DEBUG, "Received a streamchunk from VDR, flag = %lu", flag);
 
diff --git a/vdr.cc b/vdr.cc
index cbab39b237eaccc4d3c03b4e60340585c7eb15dd..c228fd85d0e86efd211f39b4c33fba18685aacea 100644 (file)
--- a/vdr.cc
+++ b/vdr.cc
@@ -30,6 +30,7 @@
 #include "wol.h"
 #include "vdrrequestpacket.h"
 #include "vdrresponsepacket.h"
+#include "command.h"
 
 VDR* VDR::instance = NULL;
 
@@ -182,7 +183,7 @@ void VDR::setReceiveWindow(size_t size)
 
 void VDR::threadMethod()
 {
-  threadSetKillable();
+  threadSetKillable(); // FIXME - change this to deal with the EDRs
   
   ULONG channelID;
   
@@ -195,21 +196,86 @@ void VDR::threadMethod()
 
   VDR_ResponsePacket* vresp;
   
+  int timeoutCount = 0;
+  
   while(1) 
   {  
-    if (!tcp->readData((UCHAR*)&channelID, sizeof(ULONG)))
+    if (!tcp->readData((UCHAR*)&channelID, sizeof(ULONG))) // 2s timeout atm
     {
+      ++timeoutCount;
+    
       // Error or timeout.
-      logger->log("VDR", Log::DEBUG, "Net read timeout");
-      
-      // Do timeouts
-      //edLock();
-      //for(EDRL::iterator i = receivers.begin(); i != receivers.end(); i++)
-      //{
-      
-      
+
+      // Thsi is the simple version of timeout system until I work out how to make it better
+      // e.g. different timeout lengths for different requests, a decent keepalive system
+      // running in parallel etc etc.
+
+      logger->log("VDR", Log::DEBUG, "Net read timeout %i", timeoutCount);
+
+      if (!tcp->isConnected())// FIXME disabled for now until it works ... !! || (timeoutCount > 10)) // 20s
+      {
+        // timeout, kill it
+
+        connected = false; // though actually it could still be connected until someone calls vdr->disconnect
+
+        // Need to wake up any waiting channel 1 request-response threads
+        // Normally this is done by a packet coming in with channelid and requestid      
+        // Instead, go through the list and for each channel 1 edr, make an empty vresp
+        // An empty vresp will have userData == NULL, which means vresp->noResponse() == true
+
+        // If it's a stream receiver, generate a stream packet with flag == connection_lost
+
+        edLock();
+        VDR_PacketReceiver* vdrpr;
+        while(receivers.size())
+        {
+          vdrpr = (VDR_PacketReceiver*) *(receivers.begin());
+          if (vdrpr->receiverChannel == CHANNEL_REQUEST_RESPONSE)
+          {
+            vresp = new VDR_ResponsePacket();
+            vresp->setResponse(vdrpr->requestSerialNumber, NULL, 0);
+            logger->log("VDR", Log::DEBUG, "Timeouts: created blank response packet for request serial %lu", vdrpr->requestSerialNumber);
+            edUnlock();
+            if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
+            {
+              // If edFindAndCall returns true, edr was called and vresp was handed off.
+              // else, delete vresp here.
+              logger->log("VDR", Log::ERR, "Timeouts: no waiting thread found for request serial %lu !!!", vdrpr->requestSerialNumber);
+              delete vresp;
+            }
+            edLock();
+          }
+          else if (vdrpr->receiverChannel == CHANNEL_STREAM)
+          {
+            vresp->setStream(vdrpr->streamID, 2 /* connection-lost flag */ , NULL, 0);
+            logger->log("VDR", Log::DEBUG, "Timeouts: created blank response packet for streamid %lu", vdrpr->streamID);
+            edUnlock();
+            if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
+            {
+              // If edFindAndCall returns true, edr was called and vresp was handed off.
+              // else, delete vresp here.
+              logger->log("VDR", Log::ERR, "Timeouts: no waiting stream receiver found for streamid %lu !!!", vdrpr->streamID);
+              delete vresp;
+            }
+            edLock();  
+          }
+        }
+        edUnlock();
+        // Ok, all event receviers should be dealt with. just in case there weren't any, inform command
+        
+        Command::getInstance()->connectionLost();
+        
+        // return and stop this thread
+        return;
+      }
+     
       continue;      
     }
+    
+    // Data was read
+    
+    timeoutCount = 0;
+    
     channelID = ntohl(channelID);
 
     vresp = new VDR_ResponsePacket();