diff --git a/Src/IACore/imp/cpp/IPC.cpp b/Src/IACore/imp/cpp/IPC.cpp index 3984bed..2d68a90 100644 --- a/Src/IACore/imp/cpp/IPC.cpp +++ b/Src/IACore/imp/cpp/IPC.cpp @@ -248,9 +248,11 @@ namespace IACore SocketOps::Close(session->ListenerSocket); session->ListenerSocket = INVALID_SOCKET; + const auto sessionID = session->ProcessHandle->ID.load(); + const auto sessionPtr = session.get(); m_activeSessions.push_back(std::move(session)); m_pendingSessions.erase(m_pendingSessions.begin() + i); - m_activeSessionMap[session->ProcessHandle->ID.load()] = session.get(); + m_activeSessionMap[sessionID] = sessionPtr; } } @@ -280,7 +282,7 @@ namespace IACore SocketOps::Close(node->DataSocket); m_activeSessions.erase(m_activeSessions.begin() + i); - m_activeSessionMap.erase(node->ProcessHandle->ID.load()); + m_activeSessionMap.erase(nodeID); } } } @@ -364,15 +366,41 @@ namespace IACore UNUSED(result); }); + // Give some time for child node to stablize + std::this_thread::sleep_for(std::chrono::seconds(1)); + if (!session->ProcessHandle->IsActive()) + return MakeUnexpected(std::format("Failed to spawn the child process \"{}\"", executablePath.string())); + + auto processID = session->ProcessHandle->ID.load(); + session->CreationTime = SteadyClock::now(); m_pendingSessions.push_back(std::move(session)); - return session->ProcessHandle->ID.load(); + return processID; } - VOID IPC_Manager::ShutdownNode(IN NativeProcessID pid) + BOOL IPC_Manager::WaitTillNodeIsOnline(IN NativeProcessID nodeID) { - const auto itNode = m_activeSessionMap.find(pid); + BOOL isPending = true; + while (isPending) + { + isPending = false; + for (auto it = m_pendingSessions.begin(); it != m_pendingSessions.end(); it++) + { + if (it->get()->ProcessHandle->ID.load() == nodeID) + { + isPending = true; + break; + } + } + Update(); + } + return m_activeSessionMap.contains(nodeID); + } + + VOID IPC_Manager::ShutdownNode(IN NativeProcessID nodeID) + { + const auto itNode = m_activeSessionMap.find(nodeID); if (itNode == m_activeSessionMap.end()) return; diff --git a/Src/IACore/imp/cpp/Logger.cpp b/Src/IACore/imp/cpp/Logger.cpp index 86c1550..0bfdc91 100644 --- a/Src/IACore/imp/cpp/Logger.cpp +++ b/Src/IACore/imp/cpp/Logger.cpp @@ -52,6 +52,13 @@ namespace IACore s_logLevel = logLevel; } + VOID Logger::FlushLogs() + { + std::cout.flush(); + if (s_logFile) + s_logFile.flush(); + } + VOID Logger::LogInternal(IN PCCHAR prefix, IN PCCHAR tag, IN String &&msg) { const auto outLine = std::format("[{:>8.3f}]: [{}]: {}", GetSecondsCount(), tag, msg); diff --git a/Src/IACore/inc/IACore/IPC.hpp b/Src/IACore/inc/IACore/IPC.hpp index 20fc8d0..df4a674 100644 --- a/Src/IACore/inc/IACore/IPC.hpp +++ b/Src/IACore/inc/IACore/IPC.hpp @@ -70,7 +70,7 @@ namespace IACore class IPC_Node { public: - ~IPC_Node(); + virtual ~IPC_Node(); // When Manager spawns a node, `connectionString` is passed // as the first command line argument @@ -121,14 +121,15 @@ namespace IACore public: IPC_Manager(); - ~IPC_Manager(); + virtual ~IPC_Manager(); VOID Update(); Expected SpawnNode(IN CONST FilePath &executablePath, IN UINT32 sharedMemorySize = DEFAULT_NODE_SHARED_MEMORY_SIZE); + BOOL WaitTillNodeIsOnline(IN NativeProcessID node); - VOID ShutdownNode(IN NativeProcessID pid); + VOID ShutdownNode(IN NativeProcessID node); VOID SendSignal(IN NativeProcessID node, IN UINT8 signal); VOID SendPacket(IN NativeProcessID node, IN UINT16 packetID, IN Span payload); diff --git a/Src/IACore/inc/IACore/Logger.hpp b/Src/IACore/inc/IACore/Logger.hpp index cb5bd3d..8cf6bb9 100644 --- a/Src/IACore/inc/IACore/Logger.hpp +++ b/Src/IACore/inc/IACore/Logger.hpp @@ -1,16 +1,16 @@ -// IACore-OSS; The Core Library for All IA Open Source Projects +// IACore-OSS; The Core Library for All IA Open Source Projects // Copyright (C) 2025 IAS (ias@iasoft.dev) -// +// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -55,8 +55,30 @@ namespace IACore LogError(std::vformat(fmt.get(), std::make_format_args(args...))); } + STATIC VOID FlushLogs(); + private: -#if IA_ENABLE_LOGGING > 0 +#if IA_DISABLE_LOGGING > 0 + STATIC VOID LogStatus(IN String &&msg) + { + UNUSED(msg); + } + + STATIC VOID LogInfo(IN String &&msg) + { + UNUSED(msg); + } + + STATIC VOID LogWarn(IN String &&msg) + { + UNUSED(msg); + } + + STATIC VOID LogError(IN String &&msg) + { + UNUSED(msg); + } +#else STATIC VOID LogStatus(IN String &&msg) { if (s_logLevel <= ELogLevel::VERBOSE) @@ -80,26 +102,6 @@ namespace IACore if (s_logLevel <= ELogLevel::ERROR) LogInternal(__CC_RED, "ERROR", IA_MOVE(msg)); } -#else - STATIC VOID LogStatus(IN String &&msg) - { - UNUSED(msg); - } - - STATIC VOID LogInfo(IN String &&msg) - { - UNUSED(msg); - } - - STATIC VOID LogWarn(IN String &&msg) - { - UNUSED(msg); - } - - STATIC VOID LogError(IN String &&msg) - { - UNUSED(msg); - } #endif STATIC VOID LogInternal(IN PCCHAR prefix, IN PCCHAR tag, IN String &&msg); @@ -114,4 +116,4 @@ namespace IACore friend VOID Initialize(); friend VOID Terminate(); }; -} \ No newline at end of file +} // namespace IACore \ No newline at end of file