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.

serviceProgram.cpp 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // \file serviceProgram.cpp
  2. //
  3. // Service program for testing CodeDweller::Service.
  4. //
  5. // Usage:
  6. //
  7. // serviceProgram <logFileName> <message>
  8. //
  9. // where <logFileName> is the name of a file to write to, and
  10. // <message> is the message callback timeout to test. <message> can
  11. // be Pause, Resume, or Stop. If <message> is anything else, then
  12. // <message> is ignored.
  13. //
  14. // This program:
  15. //
  16. // 1) Sets the callback timeout to 500 ms.
  17. //
  18. // 2) Registers callbacks for various messages. Each callback
  19. // normaly sleeps for 400 ms, which is less than the timeout.
  20. // However, if <message> is present, the callback for the specified
  21. // message sleeps for 600 ms. This should cause the service to
  22. // exit.
  23. //
  24. // 3) While the stop flag is false, outputs the status of all flags
  25. // to the log file every 2 seconds, and clears all flags.
  26. //
  27. // 4) After Stop is received, output the status of all flags, and
  28. // exit.
  29. //
  30. // Copyright (C) 2014 MicroNeil Research Corporation.
  31. //
  32. // This program is part of the MicroNeil Research Open Library Project. For
  33. // more information go to http://www.microneil.com/OpenLibrary/index.html
  34. //
  35. // This program is free software; you can redistribute it and/or modify it
  36. // under the terms of the GNU General Public License as published by the
  37. // Free Software Foundation; either version 2 of the License, or (at your
  38. // option) any later version.
  39. //
  40. // This program is distributed in the hope that it will be useful, but WITHOUT
  41. // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  42. // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  43. // more details.
  44. //
  45. // You should have received a copy of the GNU General Public License along with
  46. // this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  47. // Place, Suite 330, Boston, MA 02111-1307 USA
  48. //==============================================================================
  49. /////////////////////////////////////////////////////////////////////////////
  50. // Configuration ////////////////////////////////////////////////////////////
  51. /////////////////////////////////////////////////////////////////////////////
  52. // How long to sleep between iterations. This value is longer for
  53. // Windows because the sc command takes about 0.7 s to execute on the
  54. // development/text Windows 7 system.
  55. #ifdef WIN32
  56. const int delayTime_ms = 2700;
  57. #else
  58. const int delayTime_ms = 2000;
  59. #endif
  60. // Callback timeout time.
  61. const int timeoutTime_ms = 500;
  62. // How long the callback takes to not exceed the timeout.
  63. const int shortSleepTime_ms = 400;
  64. // How long the callback takes to exceed the timeout.
  65. const int longSleepTime_ms = 600;
  66. /////////////////////////////////////////////////////////////////////////////
  67. // End of configuration /////////////////////////////////////////////////////
  68. /////////////////////////////////////////////////////////////////////////////
  69. #include <cstdlib>
  70. #include <fstream>
  71. #include <thread>
  72. #include "CodeDweller/service.hpp"
  73. /// Callback functor for Pause message.
  74. class PauseCallback : public CodeDweller::Service::Callback {
  75. public:
  76. PauseCallback() : pauseFlag(false) {}
  77. // Total sleep time for all Pause callbacks should be less than 1000
  78. // ms. Reason: The while loop below sleeps for two seconds, and the
  79. // buildAndRun script sends the message one second into the sleep.
  80. // The callbacks must be completed before the main loop checks the
  81. // pauseFlag value.
  82. //
  83. // This applies to ResumeCallback and StopCallback.
  84. int sleepTime_ms = shortSleepTime_ms;
  85. bool pauseFlag;
  86. void operator()() {
  87. std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime_ms));
  88. pauseFlag = true;
  89. }
  90. };
  91. PauseCallback pauseCbck;
  92. PauseCallback pauseCbck1;
  93. /// Callback functor for Resume message.
  94. class ResumeCallback : public CodeDweller::Service::Callback {
  95. public:
  96. ResumeCallback() : resumeFlag(false) {}
  97. int sleepTime_ms = shortSleepTime_ms;
  98. bool resumeFlag;
  99. void operator()() {
  100. std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime_ms));
  101. resumeFlag = true;
  102. }
  103. };
  104. ResumeCallback resumeCbck;
  105. ResumeCallback resumeCbck1;
  106. /// Callback functor for Stop message.
  107. class StopCallback : public CodeDweller::Service::Callback {
  108. public:
  109. StopCallback() : stopFlag(false) {}
  110. int sleepTime_ms = shortSleepTime_ms;
  111. bool stopFlag;
  112. void operator()() {
  113. std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime_ms));
  114. stopFlag = true;
  115. }
  116. };
  117. StopCallback stopCbck;
  118. StopCallback stopCbck1;
  119. StopCallback notStopCbck;
  120. int CodeDweller::Service::run() {
  121. // Set the callback timeout to the default.
  122. CodeDweller::Service::setStopCallbackTimeout_ms(timeoutTime_ms);
  123. // Get the log file name.
  124. auto arguments = CodeDweller::Service::arguments();
  125. if (arguments.size() == 3) {
  126. // Increase the time it takes for a callback to execute.
  127. if (arguments[2] == "Pause") {
  128. pauseCbck.sleepTime_ms = longSleepTime_ms;
  129. pauseCbck1.sleepTime_ms = longSleepTime_ms;
  130. } else if (arguments[2] == "Resume") {
  131. resumeCbck.sleepTime_ms = longSleepTime_ms;
  132. resumeCbck1.sleepTime_ms = longSleepTime_ms;
  133. } else if (arguments[2] == "Stop") {
  134. stopCbck.sleepTime_ms = longSleepTime_ms;
  135. stopCbck1.sleepTime_ms = longSleepTime_ms;
  136. }
  137. }
  138. if ( (arguments.size() != 2) && (arguments.size() != 3) ) {
  139. return(EXIT_FAILURE);
  140. }
  141. // Get log file.
  142. std::ofstream logStream(arguments[1], std::fstream::app);
  143. // Register the callbacks.
  144. CodeDweller::Service::onPauseCall(pauseCbck);
  145. CodeDweller::Service::onPauseCall(pauseCbck1);
  146. CodeDweller::Service::onResumeCall(resumeCbck);
  147. CodeDweller::Service::onResumeCall(resumeCbck1);
  148. CodeDweller::Service::onStopCall(stopCbck);
  149. CodeDweller::Service::onStopCall(stopCbck1);
  150. while (!stopCbck.stopFlag) {
  151. logStream << "Sleeping 2 s...";
  152. logStream.flush();
  153. std::this_thread::sleep_for(std::chrono::milliseconds(delayTime_ms));
  154. logStream << "done." << std::endl;
  155. logStream << "receivedPause(): "
  156. << CodeDweller::Service::receivedPause() << std::endl;
  157. logStream << "receivedResume(): "
  158. << CodeDweller::Service::receivedResume() << std::endl;
  159. logStream << "receivedStop(): "
  160. << CodeDweller::Service::receivedStop() << std::endl;
  161. logStream << "Clearing all flags." << std::endl;
  162. CodeDweller::Service::clearReceivedPause();
  163. CodeDweller::Service::clearReceivedResume();
  164. CodeDweller::Service::clearReceivedStop();
  165. logStream << "receivedPause(): "
  166. << CodeDweller::Service::receivedPause() << std::endl;
  167. logStream << "receivedResume(): "
  168. << CodeDweller::Service::receivedResume() << std::endl;
  169. logStream << "receivedStop(): "
  170. << CodeDweller::Service::receivedStop() << std::endl;
  171. logStream << "pauseCbck.pauseFlag: " << pauseCbck.pauseFlag << std::endl;
  172. logStream << "pauseCbck1.pauseFlag: " << pauseCbck1.pauseFlag << std::endl;
  173. logStream << "resumeCbck.resumeFlag: " << resumeCbck.resumeFlag
  174. << std::endl;
  175. logStream << "resumeCbck1.resumeFlag: " << resumeCbck1.resumeFlag
  176. << std::endl;
  177. logStream << "stopCbck.stopFlag: " << stopCbck.stopFlag << std::endl;
  178. logStream << "stopCbck1.stopFlag: " << stopCbck1.stopFlag << std::endl;
  179. logStream << "notStopCbck.stopFlag: " << notStopCbck.stopFlag << std::endl;
  180. pauseCbck.pauseFlag = false;
  181. pauseCbck1.pauseFlag = false;
  182. resumeCbck.resumeFlag = false;
  183. resumeCbck1.resumeFlag = false;
  184. logStream << std::endl;
  185. }
  186. logStream << "Exiting." << std::endl;
  187. logStream.close();
  188. return(EXIT_SUCCESS);
  189. }