nostalgia/deps/ox/src/ox/logconn/logconn.cpp

108 lines
2.4 KiB
C++

/*
* Copyright 2015 - 2023 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifdef OX_USE_STDLIB
#include <cstdio>
#include <sys/types.h>
#ifndef _WIN32
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#else
#include <winsock.h>
#undef interface
#undef min
#undef max
#endif
#include "logconn.hpp"
#include <ox/std/bit.hpp>
namespace ox {
using namespace trace;
void closeSock(auto s) noexcept {
#ifdef _WIN32
closesocket(s);
#else
close(s);
#endif
}
LoggerConn::LoggerConn() noexcept: m_netThread([this]{this->msgSend();}) {
}
LoggerConn::~LoggerConn() noexcept {
m_running = false;
m_waitCond.notify_one();
m_netThread.join();
if (m_socket) {
closeSock(m_socket);
}
}
ox::Error LoggerConn::initConn(ox::CRStringView appName) noexcept {
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(5590);
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
oxReturnError(OxError(static_cast<ox::ErrorCode>(connect(m_socket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
return sendInit({.appName = ox::BasicString<128>(appName)});
}
ox::Error LoggerConn::send(const char *buff, std::size_t len) const noexcept {
std::size_t totalSent = 0;
while (totalSent < len) {
//std::fprintf(stdout, "Sending %lu/%lu bytes on socket %d\n", len, totalSent, m_socket);
const auto sent = ::send(m_socket, buff, len, 0);
if (sent < 0) {
std::fprintf(stderr, "Could not send msg\n");
return OxError(1, "Could not send msg");
}
totalSent += static_cast<std::size_t>(sent);
}
return {};
}
ox::Error LoggerConn::send(const TraceMsg &msg) noexcept {
return send(MsgId::TraceEvent, msg);
}
ox::Error LoggerConn::sendInit(const InitTraceMsg &msg) noexcept {
return send(MsgId::Init, msg);
}
void LoggerConn::msgSend() noexcept {
while (true) {
std::unique_lock lk(m_waitMut);
m_waitCond.wait(lk);
if (!m_running) {
break;
}
std::lock_guard buffLk(m_buffMut);
while (true) {
ox::Array<char, ox::units::KB> tmp;
const auto read = m_buff.read(tmp.data(), tmp.size());
if (!read) {
break;
}
//std::printf("LoggerConn: sending %lu bytes\n", read);
oxIgnoreError(send(tmp.data(), read));
}
}
}
}
#endif