aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-03-10 08:12:33 +0100
committerGitHub <[email protected]>2024-03-10 08:12:33 +0100
commit9815da7a63d979653ac71370ce63a4397777c715 (patch)
treec0d5675c3416fe0b487c4ef2a853a5de39ee6e2e /src
parentAdd WriteMeasuredVarUInt to avoid measuring ints twice before writing (#665) (diff)
downloadzen-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.cpp21
-rw-r--r--src/zenhttp/servers/httpasio.cpp29
-rw-r--r--src/zenutil/zenserverprocess.cpp6
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];
+ }
}
}