|
|
|
|
|
|
|
|
#include <vector> |
|
|
#include <vector> |
|
|
#include <mutex> |
|
|
#include <mutex> |
|
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32 |
|
|
|
|
|
|
|
|
|
|
|
int _tmain(int argc, TCHAR *argv[]); |
|
|
|
|
|
|
|
|
|
|
|
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv); |
|
|
|
|
|
|
|
|
|
|
|
VOID WINAPI ServiceCtrlHandler(DWORD message); |
|
|
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]); |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
namespace CodeDweller { |
|
|
namespace CodeDweller { |
|
|
|
|
|
|
|
|
/** Singleton class that implements a daemon (*nix) or service |
|
|
/** Singleton class that implements a daemon (*nix) or service |
|
|
|
|
|
|
|
|
{ |
|
|
{ |
|
|
public: |
|
|
public: |
|
|
|
|
|
|
|
|
/// Get the instance of the singleton. |
|
|
|
|
|
// |
|
|
|
|
|
// \returns a reference to the singleton. |
|
|
|
|
|
// |
|
|
|
|
|
static Service& getInstance(); |
|
|
|
|
|
|
|
|
|
|
|
/// Callback functor interface. |
|
|
/// Callback functor interface. |
|
|
class Callback { |
|
|
class Callback { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/// 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[]); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32 |
|
|
|
|
|
|
|
|
|
|
|
/// Service entry point for Windows. |
|
|
|
|
|
// \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 serviceMain(DWORD argc, LPTSTR *argv); |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
/// Register a callback for receipt of Pause. |
|
|
/// Register a callback for receipt of Pause. |
|
|
// |
|
|
// |
|
|
// \param[in] pauseFunctor is the function object to invoke when |
|
|
// \param[in] pauseFunctor is the function object to invoke when |
|
|
// Pause is received. |
|
|
// Pause is received. |
|
|
// |
|
|
// |
|
|
void onPauseCall(Callback &pauseFunctor); |
|
|
|
|
|
|
|
|
static void onPauseCall(Callback &pauseFunctor); |
|
|
|
|
|
|
|
|
/// Register a callback for receipt of Resume. |
|
|
/// Register a callback for receipt of Resume. |
|
|
// |
|
|
// |
|
|
// \param[in] resumeFunctor is the function object to invoke when |
|
|
// \param[in] resumeFunctor is the function object to invoke when |
|
|
// Resume is received. |
|
|
// Resume is received. |
|
|
// |
|
|
// |
|
|
void onResumeCall(Callback &resumeFunctor); |
|
|
|
|
|
|
|
|
static void onResumeCall(Callback &resumeFunctor); |
|
|
|
|
|
|
|
|
/// Register a callback for receipt of Stop. |
|
|
/// Register a callback for receipt of Stop. |
|
|
// |
|
|
// |
|
|
// \param[in] stopFunctor is the function object to invoke when |
|
|
// \param[in] stopFunctor is the function object to invoke when |
|
|
// Stop is received. |
|
|
// Stop is received. |
|
|
// |
|
|
// |
|
|
void onStopCall(Callback &stopFunctor); |
|
|
|
|
|
|
|
|
static void onStopCall(Callback &stopFunctor); |
|
|
|
|
|
|
|
|
/// Check whether Pause was received. |
|
|
/// Check whether Pause was received. |
|
|
// |
|
|
// |
|
|
// \returns if the Pause message was received, false otherwise. |
|
|
// \returns if the Pause message was received, false otherwise. |
|
|
// |
|
|
// |
|
|
bool receivedPause(); |
|
|
|
|
|
|
|
|
static bool receivedPause(); |
|
|
|
|
|
|
|
|
/// Check whether Resume was received. |
|
|
/// Check whether Resume was received. |
|
|
// |
|
|
// |
|
|
// \returns if the Resume message was received, false otherwise. |
|
|
// \returns if the Resume message was received, false otherwise. |
|
|
// |
|
|
// |
|
|
bool receivedResume(); |
|
|
|
|
|
|
|
|
static bool receivedResume(); |
|
|
|
|
|
|
|
|
/// Check whether the last message received was Stop. |
|
|
/// Check whether the last message received was Stop. |
|
|
// |
|
|
// |
|
|
// \returns true if Stop was the most recent message received, |
|
|
// \returns true if Stop was the most recent message received, |
|
|
// false otherwise. |
|
|
// false otherwise. |
|
|
// |
|
|
// |
|
|
bool receivedStop(); |
|
|
|
|
|
|
|
|
static bool receivedStop(); |
|
|
|
|
|
|
|
|
/// Clear receiving the Pause message. |
|
|
/// Clear receiving the Pause message. |
|
|
void clearReceivedPause(); |
|
|
|
|
|
|
|
|
static void clearReceivedPause(); |
|
|
|
|
|
|
|
|
/// Clear receiving the Resume message. |
|
|
/// Clear receiving the Resume message. |
|
|
void clearReceivedResume(); |
|
|
|
|
|
|
|
|
static void clearReceivedResume(); |
|
|
|
|
|
|
|
|
/// Clear receiving the Stop message. |
|
|
/// Clear receiving the Stop message. |
|
|
void clearReceivedStop(); |
|
|
|
|
|
|
|
|
static void clearReceivedStop(); |
|
|
|
|
|
|
|
|
/// Get a reference to the command-line arguments. |
|
|
/// Get a reference to the command-line arguments. |
|
|
// |
|
|
// |
|
|
|
|
|
|
|
|
// the application. Index i corresponds to command-line argument |
|
|
// the application. Index i corresponds to command-line argument |
|
|
// i. |
|
|
// i. |
|
|
// |
|
|
// |
|
|
const std::vector<std::string> &arguments(); |
|
|
|
|
|
|
|
|
static const std::vector<std::string> &arguments(); |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Prevent assignment. |
|
|
/// Prevent assignment. |
|
|
void operator=(Service const&) {} |
|
|
void operator=(Service const&) {} |
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
/// Get the instance of the singleton. |
|
|
|
|
|
// |
|
|
|
|
|
// \returns a reference to the singleton. |
|
|
|
|
|
// |
|
|
|
|
|
static Service& getInstance(); |
|
|
|
|
|
|
|
|
|
|
|
/// 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[]); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32 |
|
|
|
|
|
|
|
|
|
|
|
/// Service entry point for Windows. |
|
|
|
|
|
// \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 serviceMain(DWORD argc, LPTSTR *argv); |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
/// Load the command-line arguments. |
|
|
/// Load the command-line arguments. |
|
|
// |
|
|
// |
|
|
// This method loads the object with the command-line parameters. |
|
|
// This method loads the object with the command-line parameters. |
|
|
|
|
|
|
|
|
// |
|
|
// |
|
|
int run(); |
|
|
int run(); |
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
/// Mutex to serialize access to the object. |
|
|
/// Mutex to serialize access to the object. |
|
|
static std::mutex objectMutex; |
|
|
static std::mutex objectMutex; |
|
|
|
|
|
|
|
|
#ifdef WIN32 |
|
|
#ifdef WIN32 |
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
/// Process messages. |
|
|
|
|
|
|
|
|
/// Process a control message. |
|
|
// |
|
|
// |
|
|
// \param[in] message is the message to process. |
|
|
// \param[in] message is the message to process. |
|
|
// |
|
|
// |
|
|
void processMessages(DWORD message); |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
|
void processCtrlMessage(DWORD message); |
|
|
|
|
|
|
|
|
#else |
|
|
#else |
|
|
/// Thread start function to receive and process messages. |
|
|
/// Thread start function to receive and process messages. |
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
/// Command-line arguments. |
|
|
/// Command-line arguments. |
|
|
std::vector<std::string> cmdLineArgs; |
|
|
|
|
|
|
|
|
static std::vector<std::string> cmdLineArgs; |
|
|
|
|
|
|
|
|
/// True if Pause message was received. |
|
|
/// True if Pause message was received. |
|
|
bool pauseReceived; |
|
|
|
|
|
|
|
|
static bool pauseReceived; |
|
|
|
|
|
|
|
|
/// True if Resume message was received. |
|
|
/// True if Resume message was received. |
|
|
bool resumeReceived; |
|
|
|
|
|
|
|
|
static bool resumeReceived; |
|
|
|
|
|
|
|
|
/// True if Stop message was received. |
|
|
/// True if Stop message was received. |
|
|
bool stopReceived; |
|
|
|
|
|
|
|
|
static bool stopReceived; |
|
|
|
|
|
|
|
|
/// Functions to invoke when the Pause is received. |
|
|
/// Functions to invoke when the Pause is received. |
|
|
std::vector<Callback *> pauseCallbacks; |
|
|
|
|
|
|
|
|
static std::vector<Callback *> pauseCallbacks; |
|
|
|
|
|
|
|
|
/// Functions to invoke when the Resume is received. |
|
|
/// Functions to invoke when the Resume is received. |
|
|
std::vector<Callback *> resumeCallbacks; |
|
|
|
|
|
|
|
|
static std::vector<Callback *> resumeCallbacks; |
|
|
|
|
|
|
|
|
/// Functions to invoke when the Stop is received. |
|
|
/// Functions to invoke when the Stop is received. |
|
|
std::vector<Callback *> stopCallbacks; |
|
|
|
|
|
|
|
|
static std::vector<Callback *> stopCallbacks; |
|
|
|
|
|
|
|
|
#ifdef WIN32 |
|
|
#ifdef WIN32 |
|
|
/// Name of service. |
|
|
|
|
|
std::string serviceName; |
|
|
|
|
|
|
|
|
|
|
|
/// Status of the service. |
|
|
/// Status of the service. |
|
|
SERVICE_STATUS serviceStatus; |
|
|
SERVICE_STATUS serviceStatus; |
|
|
|
|
|
|
|
|
/// Handle for accessing service status on the OS. |
|
|
/// Handle for accessing service status on the OS. |
|
|
SERVICE_STATUS_HANDLE serviceStatusHandle = NULL; |
|
|
SERVICE_STATUS_HANDLE serviceStatusHandle = NULL; |
|
|
|
|
|
|
|
|
|
|
|
friend int ::_tmain(int argc, TCHAR *argv[]); |
|
|
|
|
|
|
|
|
|
|
|
friend VOID WINAPI ::ServiceMain(DWORD argc, LPTSTR *argv); |
|
|
|
|
|
|
|
|
|
|
|
friend VOID WINAPI ::ServiceCtrlHandler(DWORD message); |
|
|
|
|
|
|
|
|
#else |
|
|
#else |
|
|
|
|
|
|
|
|
/// Set of signals to wait for. |
|
|
/// Set of signals to wait for. |
|
|
sigset_t signalSet; |
|
|
sigset_t signalSet; |
|
|
|
|
|
|
|
|
|
|
|
friend int ::main(int argc, char *argv[]); |
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
}; |
|
|
}; |