|
|
|
|
|
|
|
|
|
|
|
// \file service.hpp |
|
|
|
|
|
// |
|
|
|
|
|
// Copyright (C) 2014 MicroNeil Research Corporation. |
|
|
|
|
|
// |
|
|
|
|
|
// This program is part of the MicroNeil Research Open Library Project. For |
|
|
|
|
|
// more information go to http://www.microneil.com/OpenLibrary/index.html |
|
|
|
|
|
// |
|
|
|
|
|
// 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 2 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, write to the Free Software Foundation, Inc., 59 Temple |
|
|
|
|
|
// Place, Suite 330, Boston, MA 02111-1307 USA |
|
|
|
|
|
//============================================================================== |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
\brief The service module provides a framework for implementing *nix |
|
|
|
|
|
daemons and Windows services. |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
#ifndef SERVICE_HPP |
|
|
|
|
|
#define SERVICE_HPP |
|
|
|
|
|
|
|
|
|
|
|
#include <string> |
|
|
|
|
|
#include <vector> |
|
|
|
|
|
|
|
|
|
|
|
namespace CodeDweller { |
|
|
|
|
|
|
|
|
|
|
|
/** Singleton class that implements a daemon (*nix) or service |
|
|
|
|
|
(Windows). |
|
|
|
|
|
|
|
|
|
|
|
This class implements a *nix daemon or a Windows service. |
|
|
|
|
|
|
|
|
|
|
|
To implement a daemon or service, implement the required methods |
|
|
|
|
|
of this class, and link with service.cpp. When compiled under |
|
|
|
|
|
*nix, the file service.cpp contains the definition of main for |
|
|
|
|
|
the *nix daemon. When compiled under Windows, the file |
|
|
|
|
|
service.cpp contains the entry points for the Windows service. |
|
|
|
|
|
|
|
|
|
|
|
Nomenclature: |
|
|
|
|
|
|
|
|
|
|
|
<ol> |
|
|
|
|
|
|
|
|
|
|
|
<li>Service is a *nix daemon or Windows service.</li> |
|
|
|
|
|
|
|
|
|
|
|
<li>Message is a posix signal or Windows message. This class |
|
|
|
|
|
supports the following messages: |
|
|
|
|
|
<ol> |
|
|
|
|
|
|
|
|
|
|
|
<li>Pause. This is the posix TSTP signal or Windows Pause |
|
|
|
|
|
message. This instructs the service to temporarily stop |
|
|
|
|
|
running.</li> |
|
|
|
|
|
|
|
|
|
|
|
<li>Resume. This is the posix CONT signal or Windows |
|
|
|
|
|
Resume message. This instructs the service to resume |
|
|
|
|
|
running after receiving a Pause message. If the service |
|
|
|
|
|
isn't temporarily stopped after receiving a Pause message, |
|
|
|
|
|
the Resume message has no effect.</li> |
|
|
|
|
|
|
|
|
|
|
|
<li>Restart. This is the posix HUP signal or Windows |
|
|
|
|
|
Restart message. This instructs the service to shut down |
|
|
|
|
|
and restart.</li> |
|
|
|
|
|
|
|
|
|
|
|
<li>Stop. This is the posix TERM signal or Windows Stop |
|
|
|
|
|
message. This instructs the service to shut down and |
|
|
|
|
|
exit.</li> |
|
|
|
|
|
|
|
|
|
|
|
</ol> |
|
|
|
|
|
|
|
|
|
|
|
</li> |
|
|
|
|
|
|
|
|
|
|
|
<li>Callback. This is a function that is executed when a |
|
|
|
|
|
message is received.</li> |
|
|
|
|
|
|
|
|
|
|
|
</ol> |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
class Service |
|
|
|
|
|
{ |
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
/// Get the instance of the singleton. |
|
|
|
|
|
static Service& getInstance() |
|
|
|
|
|
{ |
|
|
|
|
|
static Service service; |
|
|
|
|
|
return service; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Callback functor interface. |
|
|
|
|
|
class Callback { |
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
/// Callback method. |
|
|
|
|
|
virtual void operator()() = 0; |
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/// Main entry point. |
|
|
|
|
|
// |
|
|
|
|
|
// \param[in] argc is the number of arguments. |
|
|
|
|
|
// |
|
|
|
|
|
// \param[in] argv is an array of strings containing the |
|
|
|
|
|
// command-line arguments. The end of the array is indicated by a |
|
|
|
|
|
// null pointer. |
|
|
|
|
|
// |
|
|
|
|
|
// \returns exit code of the service. |
|
|
|
|
|
// |
|
|
|
|
|
int main(int argc, char *argv[]); |
|
|
|
|
|
|
|
|
|
|
|
/// Register a callback for receipt of Stop. |
|
|
|
|
|
// |
|
|
|
|
|
// \param[in] stopFunctor is the function object to invoke when |
|
|
|
|
|
// Stop is received. |
|
|
|
|
|
// |
|
|
|
|
|
void onStopCall(Callback *stopFunctor); |
|
|
|
|
|
|
|
|
|
|
|
/// Check whether the last message received was Stop. |
|
|
|
|
|
// |
|
|
|
|
|
// \returns true if Stop was the most recent message received, |
|
|
|
|
|
// false otherwise. |
|
|
|
|
|
// |
|
|
|
|
|
bool receivedStop(); |
|
|
|
|
|
|
|
|
|
|
|
/// Get a reference to the command-line arguments. |
|
|
|
|
|
// |
|
|
|
|
|
// \returns a reference to the vector of command-line arguments of |
|
|
|
|
|
// the application. Index i corresponds to command-line argument |
|
|
|
|
|
// i. |
|
|
|
|
|
// |
|
|
|
|
|
const std::vector<std::string> &arguments(); |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
|
|
|
|
/// Private constructor prevents instantiation. |
|
|
|
|
|
Service(); |
|
|
|
|
|
|
|
|
|
|
|
/// Prevent copying. |
|
|
|
|
|
Service(Service const&) {} |
|
|
|
|
|
|
|
|
|
|
|
/// Prevent assignment. |
|
|
|
|
|
void operator=(Service const&) {} |
|
|
|
|
|
|
|
|
|
|
|
/// Load the command-line arguments. |
|
|
|
|
|
// |
|
|
|
|
|
// This method loads the object with the command-line parameters. |
|
|
|
|
|
// |
|
|
|
|
|
// \param[in] argc is the number of arguments. |
|
|
|
|
|
// |
|
|
|
|
|
// \param[in] argv is an array of strings containing the |
|
|
|
|
|
// command-line arguments. The end of the array is indicated by a |
|
|
|
|
|
// null pointer. |
|
|
|
|
|
// |
|
|
|
|
|
void loadArguments(int argc, char *argv[]); |
|
|
|
|
|
|
|
|
|
|
|
/// Initialize and run the application. |
|
|
|
|
|
// |
|
|
|
|
|
// \returns the exit status of the service. |
|
|
|
|
|
// |
|
|
|
|
|
int run(); |
|
|
|
|
|
|
|
|
|
|
|
/// Thread start function to receive messages. |
|
|
|
|
|
void processMessages(); |
|
|
|
|
|
|
|
|
|
|
|
/// Command-line arguments. |
|
|
|
|
|
std::vector<std::string> cmdLineArgs; |
|
|
|
|
|
|
|
|
|
|
|
/// Enumeration specifying the most recent message received. |
|
|
|
|
|
enum class Message { |
|
|
|
|
|
Pause, |
|
|
|
|
|
Resume, |
|
|
|
|
|
Restart, |
|
|
|
|
|
Stop, |
|
|
|
|
|
None |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/// Most recent message received. |
|
|
|
|
|
Message lastMessage; |
|
|
|
|
|
|
|
|
|
|
|
/// Functions to invoke when the Stop is received. |
|
|
|
|
|
std::vector<Callback *> stopCallbacks; |
|
|
|
|
|
|
|
|
|
|
|
/// Set of signals to wait for. |
|
|
|
|
|
sigset_t signalSet; |
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif // SERVICE_HPP |