From c27722b3e8711291ed4db3466f8d947b70b6d856 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Tue, 26 Oct 2021 08:25:26 +0200 Subject: Fixed crash at startup when updating manifest. --- zenserver/zenserver.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'zenserver/zenserver.cpp') diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp index 4cbb56915..de30c5425 100644 --- a/zenserver/zenserver.cpp +++ b/zenserver/zenserver.cpp @@ -561,7 +561,6 @@ ZenServer::InitializeState(ZenServiceConfig& ServiceConfig) CbObjectWriter Cbo; Cbo << "schema_version" << ZEN_SCHEMA_VERSION << "created" << Now << "updated" << Now << "state_id" << Oid::NewOid(); - Cbo << m_RootManifest["id"]; m_RootManifest = Cbo.Save(); -- cgit v1.2.3 From 3bbb0d326bec3b3379c831b6a4cdc00438ac67f5 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 27 Oct 2021 21:01:50 +0200 Subject: Lockfile implementation (#24) Implemented lockfile synchronization To be used instead of or in conjunction with existing events to coordinate launching and discovery of server instances --- zenserver/zenserver.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 10 deletions(-) (limited to 'zenserver/zenserver.cpp') diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp index de30c5425..00abed513 100644 --- a/zenserver/zenserver.cpp +++ b/zenserver/zenserver.cpp @@ -8,11 +8,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -295,11 +297,13 @@ public: const bool IsInteractiveMode = zen::IsInteractiveSession() && !m_TestMode; - m_CurrentState = kRunning; + SetNewState(kRunning); + + OnReady(); m_Http->Run(IsInteractiveMode); - m_CurrentState = kShuttingDown; + SetNewState(kShuttingDown); ZEN_INFO(ZEN_APP_NAME " exiting"); @@ -321,6 +325,10 @@ public: void SetDataRoot(std::filesystem::path Root) { m_DataRoot = Root; } void SetContentRoot(std::filesystem::path Root) { m_ContentRoot = Root; } + std::function m_IsReadyFunc; + void SetIsReadyFunc(std::function&& IsReadyFunc) { m_IsReadyFunc = std::move(IsReadyFunc); } + void OnReady(); + void EnsureIoRunner() { if (!m_IoRunner.joinable()) @@ -434,6 +442,8 @@ private: kShuttingDown } m_CurrentState = kInitializing; + inline void SetNewState(ServerState NewState) { m_CurrentState = NewState; } + std::string_view ToString(ServerState Value) { switch (Value) @@ -474,6 +484,17 @@ private: bool m_DebugOptionForcedCrash = false; }; +void +ZenServer::OnReady() +{ + m_ServerEntry->SignalReady(); + + if (m_IsReadyFunc) + { + m_IsReadyFunc(); + } +} + void ZenServer::InitializeState(ZenServiceConfig& ServiceConfig) { @@ -681,6 +702,7 @@ public: private: ZenServerOptions& m_GlobalOptions; ZenServiceConfig& m_ServiceConfig; + zen::LockFile m_LockFile; }; int @@ -703,6 +725,32 @@ ZenWindowsService::Run() try { + // Mutual exclusion and synchronization + + std::error_code Ec; + + std::filesystem::path LockFilePath = GlobalOptions.DataDir / ".lock"; + + bool IsReady = false; + + auto MakeLockData = [&] { + CbObjectWriter Cbo; + Cbo << "pid" << _getpid() << "data" << ToUtf8(GlobalOptions.DataDir) << "port" << GlobalOptions.BasePort << "session_id" + << GetSessionId() << "ready" << IsReady; + return Cbo.Save(); + }; + + m_LockFile.Create(LockFilePath, MakeLockData(), Ec); + + if (Ec) + { + ConsoleLog().error("ERROR: Unable to grab lock at '{}' (error: '{}')", LockFilePath, Ec.message()); + + std::exit(99); + } + + InitializeLogging(GlobalOptions); + // Prototype config system, we'll see how this pans out // // TODO: we need to report any parse errors here @@ -764,13 +812,19 @@ ZenWindowsService::Run() }}); // If we have a parent process, establish the mechanisms we need - // to be able to communicate with the parent + // to be able to communicate readiness with the parent - if (!GlobalOptions.ChildId.empty()) - { - zen::NamedEvent ParentEvent{GlobalOptions.ChildId}; - ParentEvent.Set(); - } + Server.SetIsReadyFunc([&] { + IsReady = true; + + m_LockFile.Update(MakeLockData(), Ec); + + if (!GlobalOptions.ChildId.empty()) + { + zen::NamedEvent ParentEvent{GlobalOptions.ChildId}; + ParentEvent.Set(); + } + }); Server.Run(); Server.Cleanup(); @@ -809,8 +863,6 @@ main(int argc, char* argv[]) std::filesystem::create_directories(GlobalOptions.DataDir); } - InitializeLogging(GlobalOptions); - #if ZEN_PLATFORM_WINDOWS if (GlobalOptions.InstallService) { -- cgit v1.2.3