mirror of
https://github.com/wiiu-env/ftpiiu_plugin.git
synced 2024-11-25 22:24:17 +01:00
Use global log instead of thread-local
This commit is contained in:
parent
3ab7a31c90
commit
1b089068c2
@ -21,7 +21,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "ftpSession.h"
|
||||
#include "log.h"
|
||||
#include "platform.h"
|
||||
#include "socket.h"
|
||||
|
||||
@ -70,9 +69,6 @@ private:
|
||||
/// \brief Thread entry point
|
||||
void threadFunc ();
|
||||
|
||||
/// \brief Log
|
||||
SharedLog m_log;
|
||||
|
||||
/// \brief Thread
|
||||
platform::Thread m_thread;
|
||||
|
||||
|
132
include/log.h
132
include/log.h
@ -20,100 +20,50 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
class Log;
|
||||
using SharedLog = std::shared_ptr<Log>;
|
||||
using WeakLog = std::weak_ptr<Log>;
|
||||
|
||||
/// \brief Log object
|
||||
class Log
|
||||
/// \brief Log level
|
||||
enum LogLevel
|
||||
{
|
||||
public:
|
||||
/// \brief Log level
|
||||
enum Level
|
||||
{
|
||||
DEBUG,
|
||||
INFO,
|
||||
ERROR,
|
||||
COMMAND,
|
||||
RESPONSE,
|
||||
};
|
||||
|
||||
~Log ();
|
||||
|
||||
/// \brief Draw log
|
||||
void draw ();
|
||||
|
||||
/// \brief Create log
|
||||
static SharedLog create ();
|
||||
|
||||
/// \brief Bind log
|
||||
/// \param log_ Log to bind
|
||||
static void bind (SharedLog log_);
|
||||
|
||||
/// \brief Add debug message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) static void debug (char const *fmt_, ...);
|
||||
/// \brief Add info message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) static void info (char const *fmt_, ...);
|
||||
/// \brief Add error message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) static void error (char const *fmt_, ...);
|
||||
/// \brief Add command message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) static void command (char const *fmt_, ...);
|
||||
/// \brief Add response message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) static void response (char const *fmt_, ...);
|
||||
|
||||
/// \brief Add log message to bound log
|
||||
/// \param level_ Log level
|
||||
/// \param fmt_ Message format
|
||||
/// \param ap_ Message arguments
|
||||
static void log (Level level_, char const *fmt_, va_list ap_);
|
||||
|
||||
/// \brief Add log message to bound log
|
||||
/// \param level_ Log level
|
||||
/// \param message_ Message to log
|
||||
static void log (Level level_, std::string_view message_);
|
||||
|
||||
private:
|
||||
Log ();
|
||||
|
||||
/// \brief Add log message
|
||||
/// \param level_ Log level
|
||||
/// \param fmt_ Message format
|
||||
/// \param ap_ Message arguments
|
||||
void _log (Level level_, char const *fmt_, va_list ap_);
|
||||
|
||||
/// \brief Log message
|
||||
struct Message
|
||||
{
|
||||
/// \brief Parameterized constructor
|
||||
/// \param level_ Log level
|
||||
/// \param message_ Log message
|
||||
Message (Level const level_, std::string message_)
|
||||
: level (level_), message (std::move (message_))
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Log level
|
||||
Level level;
|
||||
/// \brief Log message
|
||||
std::string message;
|
||||
};
|
||||
|
||||
/// \brief Log messages
|
||||
std::vector<Message> m_messages;
|
||||
|
||||
/// \brief Log lock
|
||||
platform::Mutex m_lock;
|
||||
DEBUG,
|
||||
INFO,
|
||||
ERROR,
|
||||
COMMAND,
|
||||
RESPONSE,
|
||||
};
|
||||
|
||||
/// \brief Draw log
|
||||
void drawLog ();
|
||||
|
||||
/// \brief Add debug message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) void debug (char const *fmt_, ...);
|
||||
|
||||
/// \brief Add info message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) void info (char const *fmt_, ...);
|
||||
|
||||
/// \brief Add error message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) void error (char const *fmt_, ...);
|
||||
|
||||
/// \brief Add command message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) void command (char const *fmt_, ...);
|
||||
|
||||
/// \brief Add response message to bound log
|
||||
/// \param fmt_ Message format
|
||||
__attribute__ ((format (printf, 1, 2))) void response (char const *fmt_, ...);
|
||||
|
||||
/// \brief Add log message to bound log
|
||||
/// \param level_ Log level
|
||||
/// \param fmt_ Message format
|
||||
/// \param ap_ Message arguments
|
||||
void addLog (LogLevel level_, char const *fmt_, va_list ap_);
|
||||
|
||||
/// \brief Add log message to bound log
|
||||
/// \param level_ Log level
|
||||
/// \param message_ Message to log
|
||||
void addLog (LogLevel level_, std::string_view message_);
|
||||
|
@ -140,7 +140,7 @@ void startNetwork ()
|
||||
return;
|
||||
|
||||
s_socuActive = true;
|
||||
Log::info ("Wifi connected\n");
|
||||
info ("Wifi connected\n");
|
||||
}
|
||||
|
||||
/// \brief Draw citro3d logo
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ftpServer.h"
|
||||
|
||||
#include "fs.h"
|
||||
#include "log.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include "imgui.h"
|
||||
@ -63,11 +64,8 @@ FtpServer::~FtpServer ()
|
||||
m_thread.join ();
|
||||
}
|
||||
|
||||
FtpServer::FtpServer (std::uint16_t const port_)
|
||||
: m_log (Log::create ()), m_port (port_), m_quit (false)
|
||||
FtpServer::FtpServer (std::uint16_t const port_) : m_port (port_), m_quit (false)
|
||||
{
|
||||
Log::bind (m_log);
|
||||
|
||||
m_thread = platform::Thread (std::bind (&FtpServer::threadFunc, this));
|
||||
}
|
||||
|
||||
@ -115,7 +113,7 @@ void FtpServer::draw ()
|
||||
#else
|
||||
ImGui::BeginChild ("Logs", ImVec2 (0, 200), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
#endif
|
||||
m_log->draw ();
|
||||
drawLog ();
|
||||
ImGui::EndChild ();
|
||||
|
||||
#ifdef _3DS
|
||||
@ -193,7 +191,7 @@ void FtpServer::handleNetworkFound ()
|
||||
m_name.resize (std::strlen (name) + 3 + 5);
|
||||
m_name.resize (std::sprintf (&m_name[0], "[%s]:%u", name, sockName.port ()));
|
||||
|
||||
Log::info ("Started server at %s\n", m_name.c_str ());
|
||||
info ("Started server at %s\n", m_name.c_str ());
|
||||
|
||||
LOCKED (m_socket = std::move (socket));
|
||||
}
|
||||
@ -205,7 +203,7 @@ void FtpServer::handleNetworkLost ()
|
||||
LOCKED (sock = std::move (m_socket));
|
||||
}
|
||||
|
||||
Log::info ("Stopped server at %s\n", m_name.c_str ());
|
||||
info ("Stopped server at %s\n", m_name.c_str ());
|
||||
}
|
||||
|
||||
void FtpServer::loop ()
|
||||
@ -266,9 +264,6 @@ void FtpServer::loop ()
|
||||
|
||||
void FtpServer::threadFunc ()
|
||||
{
|
||||
// bind log for this thread
|
||||
Log::bind (m_log);
|
||||
|
||||
while (!m_quit)
|
||||
loop ();
|
||||
}
|
||||
|
@ -368,27 +368,27 @@ UniqueFtpSession FtpSession::create (UniqueSocket commandSocket_)
|
||||
bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
|
||||
{
|
||||
// poll for pending close sockets first
|
||||
std::vector<Socket::PollInfo> info;
|
||||
std::vector<Socket::PollInfo> pollInfo;
|
||||
for (auto &session : sessions_)
|
||||
{
|
||||
for (auto &pending : session->m_pendingCloseSocket)
|
||||
{
|
||||
assert (pending.unique ());
|
||||
info.emplace_back (Socket::PollInfo{*pending, POLLIN, 0});
|
||||
pollInfo.emplace_back (Socket::PollInfo{*pending, POLLIN, 0});
|
||||
}
|
||||
}
|
||||
|
||||
if (!info.empty ())
|
||||
if (!pollInfo.empty ())
|
||||
{
|
||||
auto const rc = Socket::poll (info.data (), info.size (), 0ms);
|
||||
auto const rc = Socket::poll (pollInfo.data (), pollInfo.size (), 0ms);
|
||||
if (rc < 0)
|
||||
{
|
||||
Log::error ("poll: %s\n", std::strerror (errno));
|
||||
error ("poll: %s\n", std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto const &i : info)
|
||||
for (auto const &i : pollInfo)
|
||||
{
|
||||
if (!i.revents)
|
||||
continue;
|
||||
@ -413,14 +413,15 @@ bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
|
||||
}
|
||||
|
||||
// poll for everything else
|
||||
info.clear ();
|
||||
pollInfo.clear ();
|
||||
for (auto &session : sessions_)
|
||||
{
|
||||
if (session->m_commandSocket)
|
||||
{
|
||||
info.emplace_back (Socket::PollInfo{*session->m_commandSocket, POLLIN | POLLPRI, 0});
|
||||
pollInfo.emplace_back (
|
||||
Socket::PollInfo{*session->m_commandSocket, POLLIN | POLLPRI, 0});
|
||||
if (session->m_responseBuffer.usedSize () != 0)
|
||||
info.back ().events |= POLLOUT;
|
||||
pollInfo.back ().events |= POLLOUT;
|
||||
}
|
||||
|
||||
switch (session->m_state)
|
||||
@ -434,12 +435,12 @@ bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
|
||||
{
|
||||
assert (!session->m_port);
|
||||
// we are waiting for a PASV connection
|
||||
info.emplace_back (Socket::PollInfo{*session->m_pasvSocket, POLLIN, 0});
|
||||
pollInfo.emplace_back (Socket::PollInfo{*session->m_pasvSocket, POLLIN, 0});
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are waiting to complete a PORT connection
|
||||
info.emplace_back (Socket::PollInfo{*session->m_dataSocket, POLLOUT, 0});
|
||||
pollInfo.emplace_back (Socket::PollInfo{*session->m_dataSocket, POLLOUT, 0});
|
||||
}
|
||||
break;
|
||||
|
||||
@ -448,25 +449,25 @@ bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
|
||||
if (session->m_recv)
|
||||
{
|
||||
assert (!session->m_send);
|
||||
info.emplace_back (Socket::PollInfo{*session->m_dataSocket, POLLIN, 0});
|
||||
pollInfo.emplace_back (Socket::PollInfo{*session->m_dataSocket, POLLIN, 0});
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (session->m_send);
|
||||
info.emplace_back (Socket::PollInfo{*session->m_dataSocket, POLLOUT, 0});
|
||||
pollInfo.emplace_back (Socket::PollInfo{*session->m_dataSocket, POLLOUT, 0});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (info.empty ())
|
||||
if (pollInfo.empty ())
|
||||
return true;
|
||||
|
||||
// poll for activity
|
||||
auto const rc = Socket::poll (info.data (), info.size (), 16ms);
|
||||
auto const rc = Socket::poll (pollInfo.data (), pollInfo.size (), 16ms);
|
||||
if (rc < 0)
|
||||
{
|
||||
Log::error ("poll: %s\n", std::strerror (errno));
|
||||
error ("poll: %s\n", std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -475,7 +476,7 @@ bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
|
||||
|
||||
for (auto &session : sessions_)
|
||||
{
|
||||
for (auto const &i : info)
|
||||
for (auto const &i : pollInfo)
|
||||
{
|
||||
if (!i.revents)
|
||||
continue;
|
||||
@ -484,7 +485,7 @@ bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
|
||||
if (&i.socket.get () == session->m_commandSocket.get ())
|
||||
{
|
||||
if (i.revents & ~(POLLIN | POLLPRI | POLLOUT))
|
||||
Log::debug ("Command revents 0x%X\n", i.revents);
|
||||
debug ("Command revents 0x%X\n", i.revents);
|
||||
|
||||
if (i.revents & POLLOUT)
|
||||
session->writeResponse ();
|
||||
@ -508,7 +509,7 @@ bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
|
||||
|
||||
case State::DATA_CONNECT:
|
||||
if (i.revents & ~(POLLIN | POLLPRI | POLLOUT))
|
||||
Log::debug ("Data revents 0x%X\n", i.revents);
|
||||
debug ("Data revents 0x%X\n", i.revents);
|
||||
|
||||
if (i.revents & (POLLERR | POLLHUP))
|
||||
{
|
||||
@ -524,7 +525,7 @@ bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
|
||||
{
|
||||
// PORT connection completed
|
||||
auto const &sockName = session->m_dataSocket->peerName ();
|
||||
Log::info ("Connected to [%s]:%u\n", sockName.name (), sockName.port ());
|
||||
info ("Connected to [%s]:%u\n", sockName.name (), sockName.port ());
|
||||
|
||||
session->sendResponse ("150 Ready\r\n");
|
||||
session->setState (State::DATA_TRANSFER, true, false);
|
||||
@ -533,7 +534,7 @@ bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
|
||||
|
||||
case State::DATA_TRANSFER:
|
||||
if (i.revents & ~(POLLIN | POLLPRI | POLLOUT))
|
||||
Log::debug ("Data revents 0x%X\n", i.revents);
|
||||
debug ("Data revents 0x%X\n", i.revents);
|
||||
|
||||
// we need to transfer data
|
||||
if (i.revents & (POLLERR | POLLHUP))
|
||||
@ -1334,7 +1335,7 @@ void FtpSession::readCommand (int const events_)
|
||||
// prepare to receive data
|
||||
if (m_commandBuffer.freeSize () == 0)
|
||||
{
|
||||
Log::error ("Exceeded command buffer size\n");
|
||||
error ("Exceeded command buffer size\n");
|
||||
closeCommand ();
|
||||
return;
|
||||
}
|
||||
@ -1349,7 +1350,7 @@ void FtpSession::readCommand (int const events_)
|
||||
if (rc == 0)
|
||||
{
|
||||
// peer closed connection
|
||||
Log::info ("Peer closed connection\n");
|
||||
info ("Peer closed connection\n");
|
||||
closeCommand ();
|
||||
return;
|
||||
}
|
||||
@ -1385,7 +1386,7 @@ void FtpSession::readCommand (int const events_)
|
||||
|
||||
*delim = '\0';
|
||||
decodePath (buffer, delim - buffer);
|
||||
Log::command ("%s\n", buffer);
|
||||
command ("%s\n", buffer);
|
||||
|
||||
char const *const command = buffer;
|
||||
|
||||
@ -1471,7 +1472,7 @@ void FtpSession::sendResponse (char const *fmt_, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt_);
|
||||
Log::log (Log::RESPONSE, fmt_, ap);
|
||||
addLog (RESPONSE, fmt_, ap);
|
||||
va_end (ap);
|
||||
|
||||
va_start (ap, fmt_);
|
||||
@ -1480,14 +1481,14 @@ void FtpSession::sendResponse (char const *fmt_, ...)
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
Log::error ("vsnprintf: %s\n", std::strerror (errno));
|
||||
error ("vsnprintf: %s\n", std::strerror (errno));
|
||||
closeCommand ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (static_cast<std::size_t> (rc) > size)
|
||||
{
|
||||
Log::error ("Not enough space for response\n");
|
||||
error ("Not enough space for response\n");
|
||||
closeCommand ();
|
||||
return;
|
||||
}
|
||||
@ -1512,14 +1513,14 @@ void FtpSession::sendResponse (std::string_view const response_)
|
||||
if (!m_commandSocket)
|
||||
return;
|
||||
|
||||
Log::log (Log::RESPONSE, response_);
|
||||
addLog (RESPONSE, response_);
|
||||
|
||||
auto const buffer = m_responseBuffer.freeArea ();
|
||||
auto const size = m_responseBuffer.freeSize ();
|
||||
|
||||
if (response_.size () > size)
|
||||
{
|
||||
Log::error ("Not enough space for response\n");
|
||||
error ("Not enough space for response\n");
|
||||
closeCommand ();
|
||||
return;
|
||||
}
|
||||
@ -1616,7 +1617,7 @@ bool FtpSession::listTransfer ()
|
||||
std::uint64_t mtime = 0;
|
||||
auto const rc = sdmc_getmtime (fullPath.c_str (), &mtime);
|
||||
if (rc != 0)
|
||||
Log::error ("sdmc_getmtime %s 0x%lx\n", fullPath.c_str (), rc);
|
||||
error ("sdmc_getmtime %s 0x%lx\n", fullPath.c_str (), rc);
|
||||
else
|
||||
st.st_mtime = mtime;
|
||||
}
|
||||
@ -2084,7 +2085,7 @@ void FtpSession::PASV (char const *args_)
|
||||
auto const &sockName = m_pasvSocket->sockName ();
|
||||
std::string name = sockName.name ();
|
||||
auto const port = sockName.port ();
|
||||
Log::info ("Listening on [%s]:%u\n", name.c_str (), port);
|
||||
info ("Listening on [%s]:%u\n", name.c_str (), port);
|
||||
|
||||
// send the address in the ftp format
|
||||
for (auto &c : name)
|
||||
|
118
source/log.cpp
118
source/log.cpp
@ -20,9 +20,12 @@
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -34,44 +37,59 @@ constexpr auto MAX_LOGS = 250;
|
||||
constexpr auto MAX_LOGS = 10000;
|
||||
#endif
|
||||
|
||||
/// \brief Bound log
|
||||
thread_local WeakLog s_log;
|
||||
|
||||
/// \brief Message prefix
|
||||
static char const *const s_prefix[] = {
|
||||
[Log::DEBUG] = "[DEBUG]",
|
||||
[Log::INFO] = "[INFO]",
|
||||
[Log::ERROR] = "[ERROR]",
|
||||
[Log::COMMAND] = "[COMMAND]",
|
||||
[Log::RESPONSE] = "[RESPONSE]",
|
||||
[DEBUG] = "[DEBUG]",
|
||||
[INFO] = "[INFO]",
|
||||
[ERROR] = "[ERROR]",
|
||||
[COMMAND] = "[COMMAND]",
|
||||
[RESPONSE] = "[RESPONSE]",
|
||||
};
|
||||
|
||||
/// \brief Log message
|
||||
struct Message
|
||||
{
|
||||
/// \brief Parameterized constructor
|
||||
/// \param level_ Log level
|
||||
/// \param message_ Log message
|
||||
Message (LogLevel const level_, std::string message_)
|
||||
: level (level_), message (std::move (message_))
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Log level
|
||||
LogLevel level;
|
||||
/// \brief Log message
|
||||
std::string message;
|
||||
};
|
||||
|
||||
/// \brief Log messages
|
||||
std::vector<Message> s_messages;
|
||||
|
||||
/// \brief Log lock
|
||||
platform::Mutex s_lock;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
Log::~Log () = default;
|
||||
|
||||
Log::Log () = default;
|
||||
|
||||
void Log::draw ()
|
||||
void drawLog ()
|
||||
{
|
||||
auto const lock = std::scoped_lock (m_lock);
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
|
||||
if (m_messages.size () > MAX_LOGS)
|
||||
if (s_messages.size () > MAX_LOGS)
|
||||
{
|
||||
auto const begin = std::begin (m_messages);
|
||||
auto const end = std::next (begin, m_messages.size () - MAX_LOGS);
|
||||
m_messages.erase (begin, end);
|
||||
auto const begin = std::begin (s_messages);
|
||||
auto const end = std::next (begin, s_messages.size () - MAX_LOGS);
|
||||
s_messages.erase (begin, end);
|
||||
}
|
||||
|
||||
static ImVec4 const s_colors[] = {
|
||||
[Log::DEBUG] = ImVec4 (1.0f, 1.0f, 0.4f, 1.0f), // yellow
|
||||
[Log::INFO] = ImVec4 (1.0f, 1.0f, 1.0f, 1.0f), // white
|
||||
[Log::ERROR] = ImVec4 (1.0f, 0.4f, 0.4f, 1.0f), // red
|
||||
[Log::COMMAND] = ImVec4 (0.4f, 1.0f, 0.4f, 1.0f), // green
|
||||
[Log::RESPONSE] = ImVec4 (0.4f, 1.0f, 1.0f, 1.0f), // cyan
|
||||
[DEBUG] = ImVec4 (1.0f, 1.0f, 0.4f, 1.0f), // yellow
|
||||
[INFO] = ImVec4 (1.0f, 1.0f, 1.0f, 1.0f), // white
|
||||
[ERROR] = ImVec4 (1.0f, 0.4f, 0.4f, 1.0f), // red
|
||||
[COMMAND] = ImVec4 (0.4f, 1.0f, 0.4f, 1.0f), // green
|
||||
[RESPONSE] = ImVec4 (0.4f, 1.0f, 1.0f, 1.0f), // cyan
|
||||
};
|
||||
|
||||
for (auto const &message : m_messages)
|
||||
for (auto const &message : s_messages)
|
||||
{
|
||||
ImGui::PushStyleColor (ImGuiCol_Text, s_colors[message.level]);
|
||||
ImGui::TextUnformatted (s_prefix[message.level]);
|
||||
@ -85,98 +103,80 @@ void Log::draw ()
|
||||
ImGui::SetScrollHereY (1.0f);
|
||||
}
|
||||
|
||||
SharedLog Log::create ()
|
||||
{
|
||||
return std::shared_ptr<Log> (new Log ());
|
||||
}
|
||||
|
||||
void Log::bind (SharedLog log_)
|
||||
{
|
||||
s_log = log_;
|
||||
}
|
||||
|
||||
void Log::debug (char const *const fmt_, ...)
|
||||
void debug (char const *const fmt_, ...)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt_);
|
||||
log (DEBUG, fmt_, ap);
|
||||
addLog (DEBUG, fmt_, ap);
|
||||
va_end (ap);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Log::info (char const *const fmt_, ...)
|
||||
void info (char const *const fmt_, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt_);
|
||||
log (INFO, fmt_, ap);
|
||||
addLog (INFO, fmt_, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void Log::error (char const *const fmt_, ...)
|
||||
void error (char const *const fmt_, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt_);
|
||||
log (ERROR, fmt_, ap);
|
||||
addLog (ERROR, fmt_, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void Log::command (char const *const fmt_, ...)
|
||||
void command (char const *const fmt_, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt_);
|
||||
log (COMMAND, fmt_, ap);
|
||||
addLog (COMMAND, fmt_, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void Log::response (char const *const fmt_, ...)
|
||||
void response (char const *const fmt_, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt_);
|
||||
log (RESPONSE, fmt_, ap);
|
||||
addLog (RESPONSE, fmt_, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void Log::log (Level const level_, char const *const fmt_, va_list ap_)
|
||||
void addLog (LogLevel const level_, char const *const fmt_, va_list ap_)
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
if (level_ == DEBUG)
|
||||
return;
|
||||
#endif
|
||||
|
||||
auto log = s_log.lock ();
|
||||
if (!log)
|
||||
return;
|
||||
|
||||
thread_local static char buffer[1024];
|
||||
|
||||
std::vsnprintf (buffer, sizeof (buffer), fmt_, ap_);
|
||||
buffer[sizeof (buffer) - 1] = '\0';
|
||||
|
||||
auto const lock = std::scoped_lock (log->m_lock);
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
#ifndef NDEBUG
|
||||
std::fprintf (stderr, "%s", s_prefix[level_]);
|
||||
std::fputs (buffer, stderr);
|
||||
#endif
|
||||
log->m_messages.emplace_back (level_, buffer);
|
||||
s_messages.emplace_back (level_, buffer);
|
||||
}
|
||||
|
||||
void Log::log (Level const level_, std::string_view const message_)
|
||||
void addLog (LogLevel const level_, std::string_view const message_)
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
if (level_ == DEBUG)
|
||||
return;
|
||||
#endif
|
||||
|
||||
auto log = s_log.lock ();
|
||||
if (!log)
|
||||
return;
|
||||
|
||||
auto msg = std::string (message_);
|
||||
for (auto &c : msg)
|
||||
{
|
||||
@ -185,10 +185,10 @@ void Log::log (Level const level_, std::string_view const message_)
|
||||
c = '?';
|
||||
}
|
||||
|
||||
auto const lock = std::scoped_lock (log->m_lock);
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
#ifndef NDEBUG
|
||||
std::fprintf (stderr, "%s", s_prefix[level_]);
|
||||
std::fwrite (msg.data (), 1, msg.size (), stderr);
|
||||
#endif
|
||||
log->m_messages.emplace_back (level_, msg);
|
||||
s_messages.emplace_back (level_, msg);
|
||||
}
|
||||
|
@ -37,13 +37,13 @@
|
||||
Socket::~Socket ()
|
||||
{
|
||||
if (m_listening)
|
||||
Log::info ("Stop listening on [%s]:%u\n", m_sockName.name (), m_sockName.port ());
|
||||
info ("Stop listening on [%s]:%u\n", m_sockName.name (), m_sockName.port ());
|
||||
|
||||
if (m_connected)
|
||||
Log::info ("Closing connection to [%s]:%u\n", m_peerName.name (), m_peerName.port ());
|
||||
info ("Closing connection to [%s]:%u\n", m_peerName.name (), m_peerName.port ());
|
||||
|
||||
if (::close (m_fd) != 0)
|
||||
Log::error ("close: %s\n", std::strerror (errno));
|
||||
error ("close: %s\n", std::strerror (errno));
|
||||
}
|
||||
|
||||
Socket::Socket (int const fd_) : m_fd (fd_), m_listening (false), m_connected (false)
|
||||
@ -67,11 +67,11 @@ UniqueSocket Socket::accept ()
|
||||
auto const fd = ::accept (m_fd, addr, &addrLen);
|
||||
if (fd < 0)
|
||||
{
|
||||
Log::error ("accept: %s\n", std::strerror (errno));
|
||||
error ("accept: %s\n", std::strerror (errno));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Log::info ("Accepted connection from [%s]:%u\n", addr.name (), addr.port ());
|
||||
info ("Accepted connection from [%s]:%u\n", addr.name (), addr.port ());
|
||||
return UniqueSocket (new Socket (fd, m_sockName, addr));
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ int Socket::atMark ()
|
||||
{
|
||||
auto const rc = ::sockatmark (m_fd);
|
||||
if (rc < 0)
|
||||
Log::error ("sockatmark: %s\n", std::strerror (errno));
|
||||
error ("sockatmark: %s\n", std::strerror (errno));
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -91,7 +91,7 @@ bool Socket::bind (SockAddr const &addr_)
|
||||
case AF_INET:
|
||||
if (::bind (m_fd, addr_, sizeof (struct sockaddr_in)) != 0)
|
||||
{
|
||||
Log::error ("bind: %s\n", std::strerror (errno));
|
||||
error ("bind: %s\n", std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -100,7 +100,7 @@ bool Socket::bind (SockAddr const &addr_)
|
||||
case AF_INET6:
|
||||
if (::bind (m_fd, addr_, sizeof (struct sockaddr_in6)) != 0)
|
||||
{
|
||||
Log::error ("bind: %s\n", std::strerror (errno));
|
||||
error ("bind: %s\n", std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -108,7 +108,7 @@ bool Socket::bind (SockAddr const &addr_)
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
Log::error ("bind: %s\n", std::strerror (errno));
|
||||
error ("bind: %s\n", std::strerror (errno));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ bool Socket::bind (SockAddr const &addr_)
|
||||
// get socket name due to request for ephemeral port
|
||||
socklen_t addrLen = sizeof (struct sockaddr_storage);
|
||||
if (::getsockname (m_fd, m_sockName, &addrLen) != 0)
|
||||
Log::error ("getsockname: %s\n", std::strerror (errno));
|
||||
error ("getsockname: %s\n", std::strerror (errno));
|
||||
}
|
||||
else
|
||||
m_sockName = addr_;
|
||||
@ -130,19 +130,19 @@ bool Socket::connect (SockAddr const &addr_)
|
||||
if (::connect (m_fd, addr_, sizeof (struct sockaddr_storage)) != 0)
|
||||
{
|
||||
if (errno != EINPROGRESS)
|
||||
Log::error ("connect: %s\n", std::strerror (errno));
|
||||
error ("connect: %s\n", std::strerror (errno));
|
||||
else
|
||||
{
|
||||
m_peerName = addr_;
|
||||
m_connected = true;
|
||||
Log::info ("Connecting to [%s]:%u\n", addr_.name (), addr_.port ());
|
||||
info ("Connecting to [%s]:%u\n", addr_.name (), addr_.port ());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
m_peerName = addr_;
|
||||
m_connected = true;
|
||||
Log::info ("Connected to [%s]:%u\n", addr_.name (), addr_.port ());
|
||||
info ("Connected to [%s]:%u\n", addr_.name (), addr_.port ());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ bool Socket::listen (int const backlog_)
|
||||
{
|
||||
if (::listen (m_fd, backlog_) != 0)
|
||||
{
|
||||
Log::error ("listen: %s\n", std::strerror (errno));
|
||||
error ("listen: %s\n", std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ bool Socket::shutdown (int const how_)
|
||||
{
|
||||
if (::shutdown (m_fd, how_) != 0)
|
||||
{
|
||||
Log::info ("shutdown: %s\n", std::strerror (errno));
|
||||
info ("shutdown: %s\n", std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -177,7 +177,7 @@ bool Socket::setLinger (bool const enable_, std::chrono::seconds const time_)
|
||||
|
||||
if (::setsockopt (m_fd, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger)) != 0)
|
||||
{
|
||||
Log::error ("setsockopt(SO_LINGER, %s, %lus): %s\n",
|
||||
error ("setsockopt(SO_LINGER, %s, %lus): %s\n",
|
||||
enable_ ? "on" : "off",
|
||||
static_cast<unsigned long> (time_.count ()),
|
||||
std::strerror (errno));
|
||||
@ -192,7 +192,7 @@ bool Socket::setNonBlocking (bool const nonBlocking_)
|
||||
auto flags = ::fcntl (m_fd, F_GETFL, 0);
|
||||
if (flags == -1)
|
||||
{
|
||||
Log::error ("fcntl(F_GETFL): %s\n", std::strerror (errno));
|
||||
error ("fcntl(F_GETFL): %s\n", std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ bool Socket::setNonBlocking (bool const nonBlocking_)
|
||||
|
||||
if (::fcntl (m_fd, F_SETFL, flags) != 0)
|
||||
{
|
||||
Log::error ("fcntl(F_SETFL, %d): %s\n", flags, std::strerror (errno));
|
||||
error ("fcntl(F_SETFL, %d): %s\n", flags, std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -215,8 +215,7 @@ bool Socket::setReuseAddress (bool const reuse_)
|
||||
int reuse = reuse_;
|
||||
if (::setsockopt (m_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof (reuse)) != 0)
|
||||
{
|
||||
Log::error (
|
||||
"setsockopt(SO_REUSEADDR, %s): %s\n", reuse_ ? "yes" : "no", std::strerror (errno));
|
||||
error ("setsockopt(SO_REUSEADDR, %s): %s\n", reuse_ ? "yes" : "no", std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -228,7 +227,7 @@ bool Socket::setRecvBufferSize (std::size_t const size_)
|
||||
int size = size_;
|
||||
if (::setsockopt (m_fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) != 0)
|
||||
{
|
||||
Log::error ("setsockopt(SO_RCVBUF, %zu): %s\n", size_, std::strerror (errno));
|
||||
error ("setsockopt(SO_RCVBUF, %zu): %s\n", size_, std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -240,7 +239,7 @@ bool Socket::setSendBufferSize (std::size_t const size_)
|
||||
int size = size_;
|
||||
if (::setsockopt (m_fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) != 0)
|
||||
{
|
||||
Log::error ("setsockopt(SO_SNDBUF, %zu): %s\n", size_, std::strerror (errno));
|
||||
error ("setsockopt(SO_SNDBUF, %zu): %s\n", size_, std::strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -253,7 +252,7 @@ ssize_t Socket::read (void *const buffer_, std::size_t const size_, bool const o
|
||||
assert (size_);
|
||||
auto const rc = ::recv (m_fd, buffer_, size_, oob_ ? MSG_OOB : 0);
|
||||
if (rc < 0 && errno != EWOULDBLOCK)
|
||||
Log::error ("recv: %s\n", std::strerror (errno));
|
||||
error ("recv: %s\n", std::strerror (errno));
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -273,7 +272,7 @@ ssize_t Socket::write (void const *const buffer_, std::size_t const size_)
|
||||
assert (size_);
|
||||
auto const rc = ::send (m_fd, buffer_, size_, 0);
|
||||
if (rc < 0 && errno != EWOULDBLOCK)
|
||||
Log::error ("send: %s\n", std::strerror (errno));
|
||||
error ("send: %s\n", std::strerror (errno));
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -302,7 +301,7 @@ UniqueSocket Socket::create ()
|
||||
auto const fd = ::socket (AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
Log::error ("socket: %s\n", std::strerror (errno));
|
||||
error ("socket: %s\n", std::strerror (errno));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -327,7 +326,7 @@ int Socket::poll (PollInfo *const info_,
|
||||
auto const rc = ::poll (pfd.get (), count_, timeout_.count ());
|
||||
if (rc < 0)
|
||||
{
|
||||
Log::error ("poll: %s\n", std::strerror (errno));
|
||||
error ("poll: %s\n", std::strerror (errno));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user