diff --git a/Source/Tools/FEXServer/Logger.cpp b/Source/Tools/FEXServer/Logger.cpp index ad827d6d3..84d166ab7 100644 --- a/Source/Tools/FEXServer/Logger.cpp +++ b/Source/Tools/FEXServer/Logger.cpp @@ -12,12 +12,8 @@ void ClientMsgHandler(int FD, FEXServerClient::Logging::PacketMsg* const Msg, co } namespace Logger { -std::vector PollFDs {}; -std::mutex IncomingPollFDsLock {}; -std::vector IncomingPollFDs {}; +int LogClientQueuePipe[2]; std::thread LogThread; -std::atomic ShouldShutdown {false}; -std::atomic LoggerThreadTID {}; void HandleLogData(int Socket) { std::vector Data(1500); @@ -58,71 +54,75 @@ void HandleLogData(int Socket) { } void LogThreadFunc() { - LoggerThreadTID = FHU::Syscalls::gettid(); + std::vector PollFDs; + PollFDs.push_back(pollfd {.fd = LogClientQueuePipe[0], .events = POLLIN | POLLHUP, .revents = 0}); - while (!ShouldShutdown) { - struct timespec ts {}; - ts.tv_sec = 5; - - { - std::unique_lock lk {IncomingPollFDsLock}; - PollFDs.insert(PollFDs.end(), std::make_move_iterator(IncomingPollFDs.begin()), std::make_move_iterator(IncomingPollFDs.end())); - IncomingPollFDs.clear(); + while (true) { + int Result = ppoll(PollFDs.data(), PollFDs.size(), nullptr, nullptr); + if (Result <= 0) { + continue; } - if (PollFDs.size() == 0) { - pselect(0, nullptr, nullptr, nullptr, &ts, nullptr); - } else { - int Result = ppoll(&PollFDs.at(0), PollFDs.size(), &ts, nullptr); - if (Result > 0) { - // Walk the FDs and see if we got any results - for (auto it = PollFDs.begin(); it != PollFDs.end();) { - bool Erase {}; - if (it->revents != 0) { - if (it->revents & POLLIN) { - // Data from the socket - HandleLogData(it->fd); - } else if (it->revents & (POLLHUP | POLLERR | POLLNVAL | POLLRDHUP)) { - // Error or hangup, close the socket and erase it from our list - Erase = true; - close(it->fd); - } - it->revents = 0; - --Result; - } + // Process events for client pipe + if (PollFDs[0].revents) { + --Result; - if (Erase) { - it = PollFDs.erase(it); - } else { - ++it; - } + auto [PipeFD, _, revents] = PollFDs[0]; + PollFDs[0].revents = 0; - if (Result == 0) { - // Early break if we've consumed all the results - break; - } - } + if (revents & POLLIN) { + int ReceivedFD; + read(PipeFD, &ReceivedFD, sizeof(ReceivedFD)); + PollFDs.push_back(pollfd { + .fd = ReceivedFD, + .events = POLLIN, + .revents = 0, + }); + } + + if (revents & POLLHUP) { + close(PipeFD); + return; + } + } + + // Process events for log FDs + for (auto it = PollFDs.begin() + 1; Result && it != PollFDs.end();) { + if (it->revents == 0) { + ++it; + continue; + } + --Result; + + bool Erase {}; + if (it->revents & POLLIN) { + // Data from the socket + HandleLogData(it->fd); + } else if (it->revents & (POLLHUP | POLLERR | POLLNVAL | POLLRDHUP)) { + // Error or hangup, close the socket and erase it from our list + Erase = true; + close(it->fd); + } + + it->revents = 0; + + if (Erase) { + it = PollFDs.erase(it); + } else { + ++it; } } } } void StartLogThread() { + pipe2(LogClientQueuePipe, 0); + LogThread = std::thread(LogThreadFunc); } void AppendLogFD(int FD) { - { - std::unique_lock lk {IncomingPollFDsLock}; - IncomingPollFDs.emplace_back(pollfd { - .fd = FD, - .events = POLLIN, - .revents = 0, - }); - } - - // Wake up the thread immediately - FHU::Syscalls::tgkill(::getpid(), LoggerThreadTID, SIGUSR1); + write(LogClientQueuePipe[1], &FD, sizeof(FD)); } bool LogThreadRunning() { @@ -130,10 +130,7 @@ bool LogThreadRunning() { } void Shutdown() { - ShouldShutdown = true; - - // Wake up the thread immediately - FHU::Syscalls::tgkill(::getpid(), LoggerThreadTID, SIGUSR1); + close(LogClientQueuePipe[1]); if (LogThread.joinable()) { LogThread.join();