diff options
| author | Dan Engelbrecht <[email protected]> | 2024-03-10 08:12:33 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-03-10 08:12:33 +0100 |
| commit | 9815da7a63d979653ac71370ce63a4397777c715 (patch) | |
| tree | c0d5675c3416fe0b487c4ef2a853a5de39ee6e2e /src | |
| parent | Add WriteMeasuredVarUInt to avoid measuring ints twice before writing (#665) (diff) | |
| download | zen-9815da7a63d979653ac71370ce63a4397777c715.tar.xz zen-9815da7a63d979653ac71370ce63a4397777c715.zip | |
fix zenserver state macos (#669)
- Shared memory for zenserver state may hang around after all zenserver processes exit - make sure we find a valid entry in `zen up` before bailing
- Httpasio add retry for desired port
- Httpasio only call listen() once
- Httpasio explicitly close acceptor sockets
Diffstat (limited to 'src')
| -rw-r--r-- | src/zen/cmds/up_cmd.cpp | 21 | ||||
| -rw-r--r-- | src/zenhttp/servers/httpasio.cpp | 29 | ||||
| -rw-r--r-- | src/zenutil/zenserverprocess.cpp | 6 |
3 files changed, 48 insertions, 8 deletions
diff --git a/src/zen/cmds/up_cmd.cpp b/src/zen/cmds/up_cmd.cpp index 837cc7edf..c5dd31f5e 100644 --- a/src/zen/cmds/up_cmd.cpp +++ b/src/zen/cmds/up_cmd.cpp @@ -38,8 +38,25 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) ZenServerState State; if (State.InitializeReadOnly()) { - ZEN_CONSOLE("Zen server already running"); - return 0; + struct EntryInfo + { + uint32_t Pid = 0; + uint16_t DesiredPort = 0; + uint16_t EffectivePort = 0; + }; + std::vector<EntryInfo> RunningEntries; + State.Snapshot([&RunningEntries](const zen::ZenServerState::ZenServerEntry& Entry) { + RunningEntries.push_back(EntryInfo{.Pid = Entry.Pid.load(), + .DesiredPort = Entry.DesiredListenPort.load(), + .EffectivePort = Entry.EffectiveListenPort.load()}); + }); + if (RunningEntries.size() > 0) + { + ZEN_CONSOLE("Zen server already running. First instance at port {}, pid {}", + RunningEntries[0].EffectivePort, + RunningEntries[0].Pid); + return 0; + } } } diff --git a/src/zenhttp/servers/httpasio.cpp b/src/zenhttp/servers/httpasio.cpp index c75057733..7ef0437c3 100644 --- a/src/zenhttp/servers/httpasio.cpp +++ b/src/zenhttp/servers/httpasio.cpp @@ -613,6 +613,13 @@ struct HttpAcceptor m_Acceptor.set_option(asio::ip::v6_only(true)); m_Acceptor.bind(asio::ip::tcp::endpoint(BindAddress, EffectivePort), BindErrorCode); } + if (BindErrorCode == asio::error::address_in_use) + { + // Do a retry after a short sleep on same port just to be sure + ZEN_INFO("Desired port %d is in use, retrying", BasePort); + Sleep(100); + m_Acceptor.bind(asio::ip::tcp::endpoint(BindAddress, EffectivePort), BindErrorCode); + } // Sharing violation implies the port is being used by another process for (uint16_t PortOffset = 1; (BindErrorCode == asio::error::address_in_use) && (PortOffset < 10); ++PortOffset) { @@ -632,7 +639,9 @@ struct HttpAcceptor { m_AlternateProtocolAcceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v4::loopback(), EffectivePort), BindErrorCode); m_UseAlternateProtocolAcceptor = true; - ZEN_INFO("Registered local-only handler 'http://{}:{}/' - this is not accessible from remote hosts", "[::1]", EffectivePort); + ZEN_INFO("Registered local-only handler 'http://{}:{}/' - this is not accessible from remote hosts", + "localhost", + EffectivePort); } #if ZEN_PLATFORM_WINDOWS @@ -675,18 +684,26 @@ struct HttpAcceptor ZEN_INFO("Started asio server at 'http://{}:{}'", BindAddress.is_loopback() ? "[::1]" : "*", EffectivePort); } + ~HttpAcceptor() + { + m_Acceptor.close(); + if (m_UseAlternateProtocolAcceptor) + { + m_AlternateProtocolAcceptor.close(); + } + } + void Start() { - m_Acceptor.listen(); + ZEN_ASSERT(!m_IsStopped); InitAcceptInternal(m_Acceptor); if (m_UseAlternateProtocolAcceptor) { - m_AlternateProtocolAcceptor.listen(); InitAcceptInternal(m_AlternateProtocolAcceptor); } } - void Stop() { m_IsStopped = true; } + void StopAccepting() { m_IsStopped = true; } int GetAcceptPort() { return m_Acceptor.local_endpoint().port(); } @@ -927,7 +944,7 @@ HttpAsioServerImpl::Stop() { if (m_Acceptor) { - m_Acceptor->Stop(); + m_Acceptor->StopAccepting(); } m_IoService.stop(); for (auto& Thread : m_ThreadPool) @@ -937,6 +954,8 @@ HttpAsioServerImpl::Stop() Thread.join(); } } + m_ThreadPool.clear(); + m_Acceptor.reset(); } void diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp index 909692fbc..0b0127f93 100644 --- a/src/zenutil/zenserverprocess.cpp +++ b/src/zenutil/zenserverprocess.cpp @@ -177,6 +177,7 @@ ZenServerState::Initialize() void* pBuf = mmap(nullptr, MapSize, PROT_READ | PROT_WRITE, MAP_SHARED, Fd, 0); if (pBuf == MAP_FAILED) { + close(Fd); ThrowLastError("Could not map view of Zen server state"); } #endif @@ -241,7 +242,10 @@ ZenServerState::Lookup(int DesiredListenPort) { if (m_Data[i].DesiredListenPort == DesiredListenPort) { - return &m_Data[i]; + if (IsProcessRunning(m_Data[i].Pid)) + { + return &m_Data[i]; + } } } |