jbus/lib/Listener.cpp

121 lines
2.9 KiB
C++
Raw Normal View History

2017-01-07 03:13:23 +00:00
#include "jbus/Listener.hpp"
#include "jbus/Endpoint.hpp"
2017-01-07 08:28:58 +00:00
#define LOG_LISTENER 0
2017-01-07 04:57:28 +00:00
2017-01-07 03:13:23 +00:00
namespace jbus
{
void Listener::listenerProc()
{
2017-01-07 04:57:28 +00:00
#if LOG_LISTENER
2017-01-07 03:13:23 +00:00
printf("JoyBus listener started\n");
2017-01-07 04:57:28 +00:00
#endif
2017-01-07 03:13:23 +00:00
net::IPAddress localhost("0.0.0.0");
bool dataBound = false;
bool clockBound = false;
while (m_running && (!dataBound || !clockBound))
{
if (!dataBound)
{
if (!(dataBound = m_dataServer.openAndListen(localhost, DataPort)))
{
m_dataServer = net::Socket(false);
2017-01-07 04:57:28 +00:00
#if LOG_LISTENER
2017-01-07 03:13:23 +00:00
printf("data open failed %s; will retry\n", strerror(errno));
2017-01-07 04:57:28 +00:00
#endif
2017-01-07 08:24:16 +00:00
WaitGCTicks(GetGCTicksPerSec());
2017-01-07 03:13:23 +00:00
}
else
2017-01-07 04:57:28 +00:00
{
#if LOG_LISTENER
2017-01-07 03:13:23 +00:00
printf("data listening on port %d\n", DataPort);
2017-01-07 04:57:28 +00:00
#endif
}
2017-01-07 03:13:23 +00:00
}
if (!clockBound)
{
if (!(clockBound = m_clockServer.openAndListen(localhost, ClockPort)))
{
m_clockServer = net::Socket(false);
2017-01-07 04:57:28 +00:00
#if LOG_LISTENER
2017-01-07 03:13:23 +00:00
printf("clock open failed %s; will retry\n", strerror(errno));
2017-01-07 04:57:28 +00:00
#endif
2017-01-07 08:24:16 +00:00
WaitGCTicks(GetGCTicksPerSec());
2017-01-07 03:13:23 +00:00
}
else
2017-01-07 04:57:28 +00:00
{
#if LOG_LISTENER
2017-01-07 03:13:23 +00:00
printf("clock listening on port %d\n", ClockPort);
2017-01-07 04:57:28 +00:00
#endif
}
2017-01-07 03:13:23 +00:00
}
}
2017-01-07 21:19:25 +00:00
/* We use blocking I/O since we have a dedicated transfer thread */
net::Socket acceptData = {true};
net::Socket acceptClock = {true};
2017-01-07 03:13:23 +00:00
std::string hostname;
u8 chan = 1;
while (m_running && chan < 4)
{
if (m_dataServer.accept(acceptData, hostname) == net::Socket::EResult::OK)
2017-01-07 04:57:28 +00:00
{
#if LOG_LISTENER
2017-01-07 03:13:23 +00:00
printf("accepted data connection from %s\n", hostname.c_str());
2017-01-07 04:57:28 +00:00
#endif
}
2017-01-07 03:13:23 +00:00
if (m_clockServer.accept(acceptClock, hostname) == net::Socket::EResult::OK)
2017-01-07 04:57:28 +00:00
{
#if LOG_LISTENER
2017-01-07 03:13:23 +00:00
printf("accepted clock connection from %s\n", hostname.c_str());
2017-01-07 04:57:28 +00:00
#endif
}
2017-01-07 03:13:23 +00:00
if (acceptData && acceptClock)
{
std::unique_lock<std::mutex> lk(m_queueLock);
m_endpointQueue.push(std::make_unique<Endpoint>(
chan++, std::move(acceptData), std::move(acceptClock)));
}
2017-01-07 08:24:16 +00:00
WaitGCTicks(GetGCTicksPerSec());
2017-01-07 03:13:23 +00:00
}
m_dataServer.close();
m_clockServer.close();
2017-01-07 04:57:28 +00:00
#if LOG_LISTENER
2017-01-07 03:13:23 +00:00
printf("JoyBus listener stopped\n");
2017-01-07 04:57:28 +00:00
#endif
2017-01-07 03:13:23 +00:00
}
void Listener::start()
{
stop();
m_running = true;
m_listenerThread = std::thread(std::bind(&Listener::listenerProc, this));
}
void Listener::stop()
{
m_running = false;
if (m_listenerThread.joinable())
m_listenerThread.join();
}
std::unique_ptr<Endpoint> Listener::accept()
{
std::unique_lock<std::mutex> lk(m_queueLock);
if (m_endpointQueue.size())
{
std::unique_ptr<Endpoint> ret;
ret = std::move(m_endpointQueue.front());
m_endpointQueue.pop();
return ret;
}
return {};
}
Listener::~Listener() { stop(); }
}