...
This commit is contained in:
parent
b6161ed03f
commit
aca8a6523e
@ -85,7 +85,7 @@ set(CNTR_PROTO_LIB_SRC
|
||||
set(CNTR_PROTO_LIB comm_proto)
|
||||
add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC})
|
||||
|
||||
set(MOUNT_SERVER_APP_SRC mount.h mount_server.cpp comm_server.h)
|
||||
set(MOUNT_SERVER_APP_SRC mount.h mount_server.cpp comm_server.h comm_server_endpoint.h)
|
||||
set(MOUNT_SERVER_APP mount_server)
|
||||
add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC})
|
||||
target_link_libraries(${MOUNT_SERVER_APP} ${CNTR_PROTO_LIB} spdlog::spdlog_header_only)
|
||||
|
||||
@ -19,6 +19,15 @@
|
||||
#include <spdlog/sinks/null_sink.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#if __has_include(<unistd.h>) // POSIX
|
||||
#define FORK_EXISTS 1
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <cerrno>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include "comm_server_endpoint.h"
|
||||
#include "control_proto.h"
|
||||
#include "mount.h"
|
||||
@ -38,25 +47,29 @@ concept mcc_endpoint_c = std::derived_from<T, asio::serial_port> || std::derived
|
||||
template <typename T>
|
||||
static constexpr bool is_serial_proto = std::derived_from<T, asio::serial_port>;
|
||||
|
||||
template <typename T>
|
||||
static constexpr bool is_tcp_proto = std::derived_from<typename T::protocol_type, asio::ip::tcp>;
|
||||
|
||||
template <typename T>
|
||||
static constexpr bool is_local_stream_proto =
|
||||
std::derived_from<typename T::protocol_type, asio::local::stream_protocol>;
|
||||
|
||||
template <typename T>
|
||||
static constexpr bool is_local_seqpack_proto =
|
||||
std::derived_from<typename T::protocol_type, asio::local::seq_packet_protocol>;
|
||||
// template <typename T>
|
||||
// static constexpr bool is_tcp_proto = std::derived_from<typename T::protocol_type, asio::ip::tcp>;
|
||||
|
||||
// template <typename T>
|
||||
// static constexpr bool is_tcp_proto = std::derived_from<T, asio::ip::tcp::endpoint>;
|
||||
// static constexpr bool is_local_stream_proto =
|
||||
// std::derived_from<typename T::protocol_type, asio::local::stream_protocol>;
|
||||
|
||||
// template <typename T>
|
||||
// static constexpr bool is_local_stream_proto = std::derived_from<T, asio::local::stream_protocol::endpoint>;
|
||||
// static constexpr bool is_local_seqpack_proto =
|
||||
// std::derived_from<typename T::protocol_type, asio::local::seq_packet_protocol>;
|
||||
|
||||
// template <typename T>
|
||||
// static constexpr bool is_local_seqpack_proto = std::derived_from<T, asio::local::seq_packet_protocol::endpoint>;
|
||||
|
||||
template <typename T>
|
||||
static constexpr bool is_tcp_proto =
|
||||
std::derived_from<T, asio::ip::tcp::endpoint> || std::derived_from<T, asio::ip::tcp::socket>;
|
||||
|
||||
template <typename T>
|
||||
static constexpr bool is_local_stream_proto = std::derived_from<T, asio::local::stream_protocol::endpoint> ||
|
||||
std::derived_from<T, asio::local::stream_protocol::socket>;
|
||||
|
||||
template <typename T>
|
||||
static constexpr bool is_local_seqpack_proto = std::derived_from<T, asio::local::seq_packet_protocol::endpoint> ||
|
||||
std::derived_from<T, asio::local::seq_packet_protocol::socket>;
|
||||
|
||||
|
||||
template <typename T>
|
||||
@ -148,8 +161,8 @@ public:
|
||||
try {
|
||||
// std::stringstream st;
|
||||
|
||||
_serverLogger->debug("Create connection acceptor for endpoint <{}> ...",
|
||||
epn.address().to_string());
|
||||
// _serverLogger->debug("Create connection acceptor for endpoint <{}> ...",
|
||||
// epn.address().to_string());
|
||||
acc = asio::ip::tcp::acceptor(_asioContext, epn);
|
||||
// st << acc.local_endpoint();
|
||||
exit_flag = true;
|
||||
@ -208,7 +221,7 @@ public:
|
||||
|
||||
st << endpoint;
|
||||
_serverLogger->debug("Create connection acceptor for endpoint <{}> ...", st.str());
|
||||
auto acc = epn_t::protocol_type::acceptor(_asioContext, endpoint);
|
||||
auto acc = typename epn_t::protocol_type::acceptor(_asioContext, endpoint);
|
||||
|
||||
st.str("");
|
||||
st << acc.local_endpoint();
|
||||
@ -240,6 +253,8 @@ public:
|
||||
} else {
|
||||
static_assert(false, "INVALID ENDPOINT!!!");
|
||||
}
|
||||
|
||||
co_return;
|
||||
}
|
||||
|
||||
|
||||
@ -247,7 +262,6 @@ public:
|
||||
void stopListening()
|
||||
{
|
||||
std::error_code ec;
|
||||
size_t N = 0, M = 0;
|
||||
|
||||
_serverLogger->info("Close all listening endpoints ...");
|
||||
|
||||
@ -291,6 +305,70 @@ public:
|
||||
|
||||
void disconnectClients() {}
|
||||
|
||||
void daemonize()
|
||||
{
|
||||
#ifdef FORK_EXISTS
|
||||
_serverLogger->info("Daemonize the server ...");
|
||||
|
||||
_asioContext.notify_fork(asio::execution_context::fork_prepare);
|
||||
|
||||
auto tmp_path = std::filesystem::temp_directory_path();
|
||||
if (tmp_path.empty()) {
|
||||
tmp_path = std::filesystem::current_path().root_path();
|
||||
}
|
||||
|
||||
|
||||
if (pid_t pid = fork()) {
|
||||
if (pid > 0) {
|
||||
exit(0);
|
||||
} else {
|
||||
// throw std::system_error(errno, std::generic_category(), "CANNOT FORK 1-STAGE");
|
||||
_serverLogger->error("CANNOT FORK 1-STAGE! The server was not daemonized!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (setsid() == -1) {
|
||||
// throw std::system_error(errno, std::generic_category(), "CANNOT FORK SETSID");
|
||||
_serverLogger->error("CANNOT FORK SETSID! The server was not daemonized!");
|
||||
return;
|
||||
}
|
||||
|
||||
_serverLogger->info("Try to set the daemon current path to '{}' ...", tmp_path.string());
|
||||
|
||||
std::error_code ec{};
|
||||
|
||||
std::filesystem::current_path(tmp_path, ec);
|
||||
if (!ec) {
|
||||
_serverLogger->warn("Cannot change current path to '{}'! Ignore!", tmp_path.string());
|
||||
}
|
||||
|
||||
umask(0);
|
||||
|
||||
if (pid_t pid = fork()) {
|
||||
if (pid > 0) {
|
||||
exit(0);
|
||||
} else {
|
||||
// throw std::system_error(errno, std::generic_category(), "CANNOT FORK 2-STAGE");
|
||||
_serverLogger->error("CANNOT FORK 2-STAGE! The server was not daemonized!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// stdin, stdout, stderr
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
|
||||
_asioContext.notify_fork(asio::io_context::fork_child);
|
||||
|
||||
_serverLogger->info("The server was daemonized successfully!");
|
||||
|
||||
#else
|
||||
_serverLogger->warn("Host platform is not POSIX one, so cannot daemonize the server!");
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
asio::io_context& _asioContext;
|
||||
std::shared_ptr<spdlog::logger> _serverLogger;
|
||||
@ -345,10 +423,11 @@ private:
|
||||
}
|
||||
|
||||
|
||||
template <traits::mcc_time_duration_c RCVT, traits::mcc_time_duration_c SNDT>
|
||||
template <traits::mcc_time_duration_c RCVT = decltype(DEFAULT_RCV_TIMEOUT),
|
||||
traits::mcc_time_duration_c SNDT = decltype(DEFAULT_SND_TIMEOUT)>
|
||||
asio::awaitable<void> startSession(auto socket,
|
||||
RCVT&& rcv_timeout = DEFAULT_RCV_TIMEOUT,
|
||||
SNDT&& snd_timeout = DEFAULT_SND_TIMEOUT)
|
||||
const RCVT& rcv_timeout = DEFAULT_RCV_TIMEOUT,
|
||||
const SNDT& snd_timeout = DEFAULT_SND_TIMEOUT)
|
||||
{
|
||||
using namespace asio::experimental::awaitable_operators;
|
||||
|
||||
@ -431,7 +510,7 @@ private:
|
||||
if constexpr (traits::is_local_seqpack_proto<sock_t>) {
|
||||
asio::socket_base::message_flags oflags;
|
||||
// nbytes = co_await socket.async_receive(buff, &oflags, asio::use_awaitable);
|
||||
nbytes = co_await (socket.async_receive(buff, &oflags, asio::use_awaitable) &&
|
||||
nbytes = co_await (socket.async_receive(buff, oflags, asio::use_awaitable) &&
|
||||
watchdog(std::chrono::steady_clock::now() + rcv_timeout));
|
||||
|
||||
if (!nbytes) { // EOF!
|
||||
|
||||
@ -438,6 +438,9 @@ protected:
|
||||
idx = std::distance(other._endpoint.c_str(), other._path.data());
|
||||
_path = std::string_view(_endpoint.c_str() + idx, other._path.size());
|
||||
|
||||
idx = std::distance(other._endpoint.c_str(), other._portView.data());
|
||||
_portView = std::string_view(_endpoint.c_str() + idx, other._portView.size());
|
||||
|
||||
_port = other._port;
|
||||
} else {
|
||||
_isValid = false;
|
||||
@ -445,6 +448,7 @@ protected:
|
||||
_proto = std::string_view();
|
||||
_host = std::string_view();
|
||||
_path = std::string_view();
|
||||
_portView = std::string_view();
|
||||
_port = -1;
|
||||
}
|
||||
}
|
||||
@ -461,12 +465,14 @@ protected:
|
||||
_host = std::move(other._host);
|
||||
_path = std::move(other._path);
|
||||
_port = std::move(other._port);
|
||||
_portView = std::move(other._portView);
|
||||
} else {
|
||||
_isValid = false;
|
||||
_endpoint = std::string();
|
||||
_proto = std::string_view();
|
||||
_host = std::string_view();
|
||||
_path = std::string_view();
|
||||
_portView = std::string_view();
|
||||
_port = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,8 +7,16 @@ int main()
|
||||
{
|
||||
asio::io_context ctx;
|
||||
|
||||
mcc::MccMountServer server(ctx, spdlog::stdout_color_mt("STDOUT_LOGGER"));
|
||||
auto logger = spdlog::stdout_color_mt("STDOUT_LOGGER");
|
||||
logger->set_level(spdlog::level::debug);
|
||||
logger->flush_on(spdlog::level::debug);
|
||||
|
||||
mcc::MccMountServer server(ctx, logger);
|
||||
|
||||
mcc::MccServerEndpoint epn(std::string_view("local://seqpacket/tmp/BM700_SERVER_SOCK"));
|
||||
// mcc::MccServerEndpoint epn(std::string_view("tcp://localhost:12345/tmp/BM700_SERVER_SOCK"));
|
||||
|
||||
asio::co_spawn(ctx, server.listen(epn), asio::detached);
|
||||
|
||||
ctx.run();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user