You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

service.hpp 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // \file service.hpp
  2. //
  3. // Copyright (C) 2014 MicroNeil Research Corporation.
  4. //
  5. // This program is part of the MicroNeil Research Open Library Project. For
  6. // more information go to http://www.microneil.com/OpenLibrary/index.html
  7. //
  8. // This program is free software; you can redistribute it and/or modify it
  9. // under the terms of the GNU General Public License as published by the
  10. // Free Software Foundation; either version 2 of the License, or (at your
  11. // option) any later version.
  12. //
  13. // This program is distributed in the hope that it will be useful, but WITHOUT
  14. // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  16. // more details.
  17. //
  18. // You should have received a copy of the GNU General Public License along with
  19. // this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  20. // Place, Suite 330, Boston, MA 02111-1307 USA
  21. //==============================================================================
  22. /*
  23. \brief The service module provides a framework for implementing *nix
  24. daemons and Windows services.
  25. */
  26. #ifndef SERVICE_HPP
  27. #define SERVICE_HPP
  28. #include <string>
  29. #include <vector>
  30. #include <mutex>
  31. namespace CodeDweller {
  32. /** Singleton class that implements a daemon (*nix) or service
  33. (Windows).
  34. This class implements a *nix daemon or a Windows service.
  35. To implement a daemon or service, implement the required methods
  36. of this class, and link with service.cpp. When compiled under
  37. *nix, the file service.cpp contains the definition of main for
  38. the *nix daemon. When compiled under Windows, the file
  39. service.cpp contains the entry points for the Windows service.
  40. Nomenclature:
  41. <ol>
  42. <li>Service is a *nix daemon or Windows service.</li>
  43. <li>Message is a posix signal or Windows message. This class
  44. supports the following messages:
  45. <ol>
  46. <li>Pause. This is the posix TSTP signal or Windows Pause
  47. message. This instructs the service to temporarily stop
  48. running.</li>
  49. <li>Resume. This is the posix CONT signal or Windows
  50. Resume message. This instructs the service to resume
  51. running after receiving a Pause message. If the service
  52. isn't temporarily stopped after receiving a Pause message,
  53. the Resume message has no effect.</li>
  54. <li>Restart. This is the posix HUP signal or Windows
  55. Restart message. This instructs the service to shut down
  56. and restart.</li>
  57. <li>Stop. This is the posix TERM signal or Windows Stop
  58. message. This instructs the service to shut down and
  59. exit.</li>
  60. </ol>
  61. </li>
  62. <li>Callback. This is a function that is executed when a
  63. message is received.</li>
  64. </ol>
  65. */
  66. class Service
  67. {
  68. public:
  69. /// Get the instance of the singleton.
  70. //
  71. // \returns a reference to the singleton.
  72. //
  73. static Service& getInstance();
  74. /// Callback functor interface.
  75. class Callback {
  76. public:
  77. /// Callback method.
  78. virtual void operator()() = 0;
  79. };
  80. /// Main entry point.
  81. //
  82. // \param[in] argc is the number of arguments.
  83. //
  84. // \param[in] argv is an array of strings containing the
  85. // command-line arguments. The end of the array is indicated by a
  86. // null pointer.
  87. //
  88. // \returns exit code of the service.
  89. //
  90. int main(int argc, char *argv[]);
  91. /// Register a callback for receipt of Pause.
  92. //
  93. // \param[in] pauseFunctor is the function object to invoke when
  94. // Pause is received.
  95. //
  96. void onPauseCall(Callback &pauseFunctor);
  97. /// Register a callback for receipt of Resume.
  98. //
  99. // \param[in] resumeFunctor is the function object to invoke when
  100. // Resume is received.
  101. //
  102. void onResumeCall(Callback &resumeFunctor);
  103. /// Register a callback for receipt of Restart.
  104. //
  105. // \param[in] restartFunctor is the function object to invoke when
  106. // Restart is received.
  107. //
  108. void onRestartCall(Callback &restartFunctor);
  109. /// Register a callback for receipt of Stop.
  110. //
  111. // \param[in] stopFunctor is the function object to invoke when
  112. // Stop is received.
  113. //
  114. void onStopCall(Callback &stopFunctor);
  115. /// Check whether Pause was received.
  116. //
  117. // \returns if the Pause message was received, false otherwise.
  118. //
  119. bool receivedPause();
  120. /// Check whether Resume was received.
  121. //
  122. // \returns if the Resume message was received, false otherwise.
  123. //
  124. bool receivedResume();
  125. /// Check whether Restart was received.
  126. //
  127. // \returns if the Restart message was received, false otherwise.
  128. //
  129. bool receivedRestart();
  130. /// Check whether the last message received was Stop.
  131. //
  132. // \returns true if Stop was the most recent message received,
  133. // false otherwise.
  134. //
  135. bool receivedStop();
  136. /// Clear receiving the Pause message.
  137. void clearReceivedPause();
  138. /// Clear receiving the Resume message.
  139. void clearReceivedResume();
  140. /// Clear receiving the Restart message.
  141. void clearReceivedRestart();
  142. /// Clear receiving the Stop message.
  143. void clearReceivedStop();
  144. /// Get a reference to the command-line arguments.
  145. //
  146. // \returns a reference to the vector of command-line arguments of
  147. // the application. Index i corresponds to command-line argument
  148. // i.
  149. //
  150. const std::vector<std::string> &arguments();
  151. private:
  152. /// Private constructor prevents instantiation.
  153. Service();
  154. /// Prevent copying.
  155. Service(Service const&) {}
  156. /// Prevent assignment.
  157. void operator=(Service const&) {}
  158. /// Load the command-line arguments.
  159. //
  160. // This method loads the object with the command-line parameters.
  161. //
  162. // \param[in] argc is the number of arguments.
  163. //
  164. // \param[in] argv is an array of strings containing the
  165. // command-line arguments. The end of the array is indicated by a
  166. // null pointer.
  167. //
  168. void loadArguments(int argc, char *argv[]);
  169. /// Initialize and run the application.
  170. //
  171. // \returns the exit status of the service.
  172. //
  173. int run();
  174. /// Mutex to serialize access to the object.
  175. static std::mutex objectMutex;
  176. /// Thread start function to receive messages.
  177. void processMessages();
  178. /// Command-line arguments.
  179. std::vector<std::string> cmdLineArgs;
  180. /// Enumeration specifying the most recent message received.
  181. enum class Message {
  182. Pause,
  183. Resume,
  184. Restart,
  185. Stop,
  186. None
  187. };
  188. /// True if Pause message was received.
  189. bool pauseReceived;
  190. /// True if Resume message was received.
  191. bool resumeReceived;
  192. /// True if Restart message was received.
  193. bool restartReceived;
  194. /// True if Stop message was received.
  195. bool stopReceived;
  196. /// Functions to invoke when the Pause is received.
  197. std::vector<Callback *> pauseCallbacks;
  198. /// Functions to invoke when the Resume is received.
  199. std::vector<Callback *> resumeCallbacks;
  200. /// Functions to invoke when the Restart is received.
  201. std::vector<Callback *> restartCallbacks;
  202. /// Functions to invoke when the Stop is received.
  203. std::vector<Callback *> stopCallbacks;
  204. /// Set of signals to wait for.
  205. sigset_t signalSet;
  206. };
  207. }
  208. #endif // SERVICE_HPP