TSSRT Support

This commit is contained in:
Phencys 2020-07-26 16:19:14 +02:00 committed by Thulinma
parent 974380ab30
commit 19199cbff8
17 changed files with 1471 additions and 15 deletions

View file

@ -3,6 +3,7 @@
#include "config.h"
#include "defines.h"
#include "lib/socket_srt.h"
#include "stream.h"
#include "timing.h"
#include "tinythread.h"
@ -30,17 +31,18 @@
#include <iostream>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h> // for va_list
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdarg.h> // for va_list
bool Util::Config::is_active = false;
bool Util::Config::is_restarting = false;
static Socket::Server *serv_sock_pointer = 0;
static Socket::SRTServer *serv_srt_sock_pointer = 0; ///< Holds a pointer to SRT Server, if it is connected
uint32_t Util::printDebugLevel = DEBUG;
std::string Util::streamName;
char Util::exitReason[256] = {0};
char Util::exitReason[256] ={0};
void Util::logExitReason(const char *format, ...){
if (exitReason[0]){return;}
@ -53,6 +55,13 @@ void Util::logExitReason(const char *format, ...){
std::string Util::listenInterface;
uint32_t Util::listenPort = 0;
// Sets pointer to the SRT Server, for proper cleanup later.
//
// Currently used for TSSRT Input only, as this doesn't use the config library to setup a listener
void Util::Config::registerSRTSockPtr(Socket::SRTServer *ptr){
serv_srt_sock_pointer = ptr;
}
Util::Config::Config(){
// global options here
vals["debug"]["long"] = "debug";
@ -202,7 +211,9 @@ bool Util::Config::parseArgs(int &argc, char **&argv){
#endif
#ifdef STAT_CUTOFF
if (STAT_CUTOFF != 600){
std::cout << "- Setting: Stats cutoff point " << STAT_CUTOFF << " seconds. Statistics and session cache are only kept for this long, as opposed to the default of 600 seconds." << std::endl;
std::cout << "- Setting: Stats cutoff point "
<< STAT_CUTOFF << " seconds. Statistics and session cache are only kept for this long, as opposed to the default of 600 seconds."
<< std::endl;
}
#endif
#ifndef SSL
@ -320,6 +331,23 @@ struct callbackData{
int (*cb)(Socket::Connection &);
};
// As above, but using an SRT Connection
struct callbackSRTData{
Socket::SRTConnection *sock;
int (*cb)(Socket::SRTConnection &);
};
// Callback for SRT-serving threads
static void callThreadCallbackSRT(void *cDataArg){
INSANE_MSG("Thread for %p started", cDataArg);
callbackSRTData *cData = (callbackSRTData *)cDataArg;
cData->cb(*(cData->sock));
cData->sock->close();
delete cData->sock;
delete cData;
INSANE_MSG("Thread for %p ended", cDataArg);
}
static void callThreadCallback(void *cDataArg){
INSANE_MSG("Thread for %p started", cDataArg);
callbackData *cData = (callbackData *)cDataArg;
@ -402,6 +430,53 @@ int Util::Config::serveThreadedSocket(int (*callback)(Socket::Connection &)){
return r;
}
// This is a THREADED server!! Fork does not work as the SRT library itself already starts up a
// thread, and forking after thread creation messes up all control flow internal to the library.
int Util::Config::serveSRTSocket(int (*callback)(Socket::SRTConnection &S)){
Socket::SRTServer server_socket;
if (vals.isMember("port") && vals.isMember("interface")){
server_socket = Socket::SRTServer(getInteger("port"), getString("interface"), false, "output");
}
if (!server_socket.connected()){
DEVEL_MSG("Failure to open socket");
return 1;
}
serv_srt_sock_pointer = &server_socket;
activate();
if (server_socket.getSocket()){
int oldSock = server_socket.getSocket();
if (!dup2(oldSock, 0)){
server_socket = Socket::SRTServer(0);
close(oldSock);
}
}
int r = SRTServer(server_socket, callback);
serv_srt_sock_pointer = 0;
return r;
}
int Util::Config::SRTServer(Socket::SRTServer &server_socket, int (*callback)(Socket::SRTConnection &)){
Util::Procs::socketList.insert(server_socket.getSocket());
while (is_active && server_socket.connected()){
Socket::SRTConnection S = server_socket.accept(false, "output");
if (S.connected()){// check if the new connection is valid
callbackSRTData *cData = new callbackSRTData;
cData->sock = new Socket::SRTConnection(S);
cData->cb = callback;
// spawn a new thread for this connection
tthread::thread T(callThreadCallbackSRT, (void *)cData);
// detach it, no need to keep track of it anymore
T.detach();
HIGH_MSG("Spawned new thread for socket %i", S.getSocket());
}else{
Util::sleep(10); // sleep 10ms
}
}
Util::Procs::socketList.erase(server_socket.getSocket());
if (!is_restarting){server_socket.close();}
return 0;
}
int Util::Config::serveForkedSocket(int (*callback)(Socket::Connection &S)){
Socket::Server server_socket;
if (Socket::checkTrueSocket(0)){
@ -466,6 +541,8 @@ void Util::Config::signal_handler(int signum, siginfo_t *sigInfo, void *ignore){
case SIGHUP:
case SIGTERM:
if (serv_sock_pointer){serv_sock_pointer->close();}
// Close the srt server as well, if set
if (serv_srt_sock_pointer){serv_srt_sock_pointer->close();}
#if DEBUG >= DLVL_DEVEL
static int ctr = 0;
if (!is_active && ++ctr > 4){BACKTRACE;}