Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ServerApplication): termination callback #4643 #4733

Merged
merged 3 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Util/include/Poco/Util/ServerApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#if defined(POCO_OS_FAMILY_WINDOWS)
#include "Poco/NamedEvent.h"
#endif
#include <functional>


namespace Poco {
Expand Down Expand Up @@ -122,8 +123,21 @@ class Util_API ServerApplication: public Application
/// --pidfile=/var/run/sample.pid) may be useful to record the process ID of
/// the daemon in a file. The PID file will be removed when the daemon process
/// terminates (but not, if it crashes).
///
/// An application can register a callback to be called at termination time.
/// An example of the termination callback registration at some point
/// during the ServerApplication initialization time:
///
/// static const std::string cbMsg = "Termination custom message"s;
/// auto tCB = [](const std::string& message)
/// {
/// std::cout << message << std::endl;
/// };
/// ServerApplication::registerTerminateCallback(tCB, cbMsg);
{
public:
using TerminateCallback = std::function<void(const std::string&)>;
aleks-f marked this conversation as resolved.
Show resolved Hide resolved

ServerApplication();
/// Creates the ServerApplication.

Expand Down Expand Up @@ -158,6 +172,11 @@ class Util_API ServerApplication: public Application
/// waitForTerminationRequest(), this method will return
/// and the application can shut down.

static void registerTerminateCallback(TerminateCallback tCB,
const std::string& message = _terminateMessage);
/// Registers a termination callback.
/// Used to notify all interested users about system shutdown.
aleks-f marked this conversation as resolved.
Show resolved Hide resolved

protected:
int run();
void waitForTerminationRequest();
Expand Down Expand Up @@ -207,6 +226,11 @@ class Util_API ServerApplication: public Application
static SERVICE_STATUS_HANDLE _serviceStatusHandle;
static Poco::NamedEvent _terminate;
#endif

static void terminateCallback();
inline static std::atomic<bool> _terminationGuard = false;
inline static TerminateCallback _terminateCallback = nullptr;
inline static std::string _terminateMessage = "System terminating now!";
};


Expand Down
25 changes: 25 additions & 0 deletions Util/src/ServerApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,22 @@ int ServerApplication::run()
}


void ServerApplication::terminateCallback()
{
if (!_terminationGuard.exchange(true))
{
if (_terminateCallback)
{
_terminateCallback(_terminateMessage);
_terminateCallback = nullptr;
}
}
}


void ServerApplication::terminate()
{
terminateCallback();
#if defined(POCO_OS_FAMILY_WINDOWS)
_terminate.set();
#elif defined(POCO_VXWORKS) || POCO_OS == POCO_OS_ANDROID
Expand All @@ -103,6 +117,13 @@ void ServerApplication::terminate()
}


void ServerApplication::registerTerminateCallback(TerminateCallback tCB, const std::string& message)
{
_terminateCallback = tCB;
_terminateMessage = message;
}


#if defined(POCO_OS_FAMILY_WINDOWS)


Expand Down Expand Up @@ -196,6 +217,7 @@ void ServerApplication::waitForTerminationRequest()
{
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
_terminate.wait();
terminateCallback();
_terminated.set();
}

Expand Down Expand Up @@ -444,6 +466,7 @@ void ServerApplication::handleStartup(const std::string& name, const std::string
void ServerApplication::waitForTerminationRequest()
{
_terminate.wait();
terminateCallback();
}


Expand Down Expand Up @@ -503,8 +526,10 @@ void ServerApplication::waitForTerminationRequest()
sigprocmask(SIG_BLOCK, &sset, NULL);
int sig;
sigwait(&sset, &sig);
terminateCallback();
#else // POCO_OS != POCO_OS_ANDROID
_terminate.wait();
terminateCallback();
#endif
}

Expand Down
Loading