return connected;
}
+void TCP::abortCall()
+{
+ ::write(abortPipe[1], "X", 1);
+}
+
bool TCP::write(void* src, ULONG numBytes)
{
if (!connected) return false;
{
if (abortCount == 5)
{
- logger->log("TCP", Log::ERR, "abortCount = 5");
+ logger->log("TCP", Log::DEBUG, "abortCount = 5");
return false;
}
if (selectResult == -1) { shutdown(); return false; }
if (selectResult == 0) return false;
- if (FD_ISSET(abortPipe[0], &readfds)) return false;
+ if (FD_ISSET(abortPipe[0], &readfds)) { logger->log("TCP", Log::DEBUG, "aborting..."); return false; }
int recvResult = recv(sockfd, pointer, numBytes - totalReceived, 0);
if (recvResult == -1) { shutdown(); return false; }
along with VOMP. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "vdr.h"
+#include <climits>
#include "recman.h"
#include "recinfo.h"
#include "seriesinfo.h"
#include "osdvector.h"
#include "tvmedia.h"
-#include <climits>
+
+#include "vdr.h"
#define VOMP_PROTOCOL_VERSION 0x00000500
channelNumberWidth = 1;
tcp.shutdown();
- if (tcp.connect(serverIP, serverPort))
- {
- connected = true;
- threadStart();
- return 1;
- }
- else
+ if (!tcp.connect(serverIP, serverPort)) return 0;
+
+ connected = true;
+
+ threadStartProtect.lock();
+ vdrThread = std::thread( [this]
{
- return 0;
- }
+ threadStartProtect.lock();
+ threadStartProtect.unlock();
+ threadMethod();
+ });
+ threadStartProtect.unlock();
+
+ return 1;
}
void VDR::disconnect()
{
- threadCancel();
+ logger->log("VDR", Log::DEBUG, "Disconnect start");
+
+ if (vdrThread.joinable())
+ {
+ threadReqStop = true;
+ tcp.abortCall();
+ vdrThread.join();
+ threadReqStop = false;
+ logger->log("VDR", Log::DEBUG, "done thread stop");
+ }
+
connected = false;
logger->log("VDR", Log::DEBUG, "Disconnect");
}
{
logger->log("VDR", Log::DEBUG, "VDR RUN");
- threadSetKillable(); // FIXME - change this to deal with the EDRs
-
ULONG channelID;
ULONG requestID;
while(1)
{
+ if (threadReqStop) return;
+
timeNow = time(NULL);
- readSuccess = tcp.read(&channelID, sizeof(ULONG)); // 2s timeout atm
+ readSuccess = tcp.read(&channelID, sizeof(ULONG));
+
+ if (threadReqStop) return;
if (!readSuccess)
{
return;
}
lastKAsent = timeNow;
+
+ if (threadReqStop) return;
}
}
else
if (channelID == CHANNEL_REQUEST_RESPONSE)
{
if (!tcp.read(&requestID, sizeof(ULONG))) break;
+ if (threadReqStop) return;
requestID = ntohl(requestID);
if (!tcp.read(&userDataLength, sizeof(ULONG))) break;
+ if (threadReqStop) return;
userDataLength = ntohl(userDataLength);
if (userDataLength > 5000000) break; // how big can these packets get?
userData = NULL;
{
userData = malloc(userDataLength);
if (!userData) break;
- if (!tcp.read(userData, userDataLength)) break;
+ if (!tcp.read(userData, userDataLength))
+ {
+ free(userData);
+ break;
+ }
+
+ if (threadReqStop)
+ {
+ free(userData);
+ return;
+ }
}
vresp = new VDR_ResponsePacket();
vresp->setResponse(requestID, reinterpret_cast<UCHAR*>(userData), userDataLength);
+ // vresp now owns userData unless something calls vresp->getUserData()
// logger->log("VDR", Log::DEBUG, "Rxd a response packet, requestID=%lu, len=%lu", requestID, userDataLength);
if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
// else, delete vresp here.
delete vresp;
}
+ if (threadReqStop) return;
}
else if (channelID == CHANNEL_STREAM || channelID == CHANNEL_TVMEDIA)
{
if (!tcp.read(&streamID, sizeof(ULONG))) break;
+ if (threadReqStop) return;
streamID = ntohl(streamID);
if (!tcp.read(&flag, sizeof(ULONG))) break;
+ if (threadReqStop) return;
flag = ntohl(flag);
if (!tcp.read(&userDataLength, sizeof(ULONG))) break;
+ if (threadReqStop) return;
userDataLength = ntohl(userDataLength);
userData = NULL;
if (userDataLength > 0)
{
userData = malloc(userDataLength);
if (!userData) break;
- if (!tcp.read(userData, userDataLength)) break;
+ if (!tcp.read(userData, userDataLength))
+ {
+ free(userData);
+ break;
+ }
+
+ if (threadReqStop)
+ {
+ free(userData);
+ return;
+ }
}
vresp = new VDR_ResponsePacket();
// else, delete vresp here.
delete vresp;
}
+
+ if (threadReqStop) return;
}
else if (channelID == CHANNEL_KEEPALIVE)
{
ULONG KAreply = 0;
if (!tcp.read(&KAreply, sizeof(ULONG))) break;
+ if (threadReqStop) return;
KAreply = ntohl(KAreply);
if (KAreply == lastKAsent) // successful KA response
{
logger->log("VDR", Log::ERR, "Rxd a response packet on channel %lu !!", channelID);
break;
}
- threadCheckExit();
-
// Who deletes vresp?
// If RR, the individual protocol functions must delete vresp.