Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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. // Callback timeout time.
  53. const int timeoutTime_ms = 500;
  54. // How long the callback takes to not exceed the timeout.
  55. const int shortSleepTime_ms = 400;
  56. // How long the callback takes to exceed the timeout.
  57. const int longSleepTime_ms = 600;
  58. /////////////////////////////////////////////////////////////////////////////
  59. // End of configuration /////////////////////////////////////////////////////
  60. /////////////////////////////////////////////////////////////////////////////
  61. #include <cstdlib>
  62. #include <fstream>
  63. #include <thread>
  64. #include "CodeDweller/service.hpp"
  65. /// Callback functor for Pause message.
  66. class PauseCallback : public CodeDweller::Service::Callback {
  67. public:
  68. PauseCallback() : pauseFlag(false) {}
  69. // Total sleep time for all Pause callbacks should be less than 1000
  70. // ms. Reason: The while loop below sleeps for two seconds, and the
  71. // buildAndRun script sends the message one second into the sleep.
  72. // The callbacks must be completed before the main loop checks the
  73. // pauseFlag value.
  74. //
  75. // This applies to ResumeCallback and StopCallback.
  76. int sleepTime_ms = shortSleepTime_ms;
  77. bool pauseFlag;
  78. void operator()() {
  79. std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime_ms));
  80. pauseFlag = true;
  81. }
  82. };
  83. PauseCallback pauseCbck;
  84. PauseCallback pauseCbck1;
  85. /// Callback functor for Resume message.
  86. class ResumeCallback : public CodeDweller::Service::Callback {
  87. public:
  88. ResumeCallback() : resumeFlag(false) {}
  89. int sleepTime_ms = shortSleepTime_ms;
  90. bool resumeFlag;
  91. void operator()() {
  92. std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime_ms));
  93. resumeFlag = true;
  94. }
  95. };
  96. ResumeCallback resumeCbck;
  97. ResumeCallback resumeCbck1;
  98. /// Callback functor for Stop message.
  99. class StopCallback : public CodeDweller::Service::Callback {
  100. public:
  101. StopCallback() : stopFlag(false) {}
  102. int sleepTime_ms = shortSleepTime_ms;
  103. bool stopFlag;
  104. void operator()() {
  105. std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime_ms));
  106. stopFlag = true;
  107. }
  108. };
  109. StopCallback stopCbck;
  110. StopCallback stopCbck1;
  111. StopCallback notStopCbck;
  112. int CodeDweller::Service::run() {
  113. // Set the callback timeout to the default.
  114. CodeDweller::Service::setCallbackTimeout_ms(timeoutTime_ms);
  115. // Get the log file name.
  116. auto arguments = CodeDweller::Service::arguments();
  117. if (arguments.size() == 3) {
  118. // Increase the time it takes for a callback to execute.
  119. if (arguments[2] == "Pause") {
  120. pauseCbck.sleepTime_ms = longSleepTime_ms;
  121. pauseCbck1.sleepTime_ms = longSleepTime_ms;
  122. } else if (arguments[2] == "Resume") {
  123. resumeCbck.sleepTime_ms = longSleepTime_ms;
  124. resumeCbck1.sleepTime_ms = longSleepTime_ms;
  125. } else if (arguments[2] == "Stop") {
  126. stopCbck.sleepTime_ms = longSleepTime_ms;
  127. stopCbck1.sleepTime_ms = longSleepTime_ms;
  128. }
  129. }
  130. if ( (arguments.size() != 2) && (arguments.size() != 3) ) {
  131. return(EXIT_FAILURE);
  132. }
  133. // Get log file.
  134. std::ofstream logStream(arguments[1], std::fstream::app);
  135. // Register the callbacks.
  136. CodeDweller::Service::onPauseCall(pauseCbck);
  137. CodeDweller::Service::onPauseCall(pauseCbck1);
  138. CodeDweller::Service::onResumeCall(resumeCbck);
  139. CodeDweller::Service::onResumeCall(resumeCbck1);
  140. CodeDweller::Service::onStopCall(stopCbck);
  141. CodeDweller::Service::onStopCall(stopCbck1);
  142. while (!stopCbck.stopFlag) {
  143. logStream << "Sleeping 2 s...";
  144. logStream.flush();
  145. std::this_thread::sleep_for(std::chrono::milliseconds(2000));
  146. logStream << "done." << std::endl;
  147. logStream << "receivedPause(): "
  148. << CodeDweller::Service::receivedPause() << std::endl;
  149. logStream << "receivedResume(): "
  150. << CodeDweller::Service::receivedResume() << std::endl;
  151. logStream << "receivedStop(): "
  152. << CodeDweller::Service::receivedStop() << std::endl;
  153. logStream << "Clearing all flags." << std::endl;
  154. CodeDweller::Service::clearReceivedPause();
  155. CodeDweller::Service::clearReceivedResume();
  156. CodeDweller::Service::clearReceivedStop();
  157. logStream << "receivedPause(): "
  158. << CodeDweller::Service::receivedPause() << std::endl;
  159. logStream << "receivedResume(): "
  160. << CodeDweller::Service::receivedResume() << std::endl;
  161. logStream << "receivedStop(): "
  162. << CodeDweller::Service::receivedStop() << std::endl;
  163. logStream << "pauseCbck.pauseFlag: " << pauseCbck.pauseFlag << std::endl;
  164. logStream << "pauseCbck1.pauseFlag: " << pauseCbck1.pauseFlag << std::endl;
  165. logStream << "resumeCbck.resumeFlag: " << resumeCbck.resumeFlag
  166. << std::endl;
  167. logStream << "resumeCbck1.resumeFlag: " << resumeCbck1.resumeFlag
  168. << std::endl;
  169. logStream << "stopCbck.stopFlag: " << stopCbck.stopFlag << std::endl;
  170. logStream << "stopCbck1.stopFlag: " << stopCbck1.stopFlag << std::endl;
  171. logStream << "notStopCbck.stopFlag: " << notStopCbck.stopFlag << std::endl;
  172. pauseCbck.pauseFlag = false;
  173. pauseCbck1.pauseFlag = false;
  174. resumeCbck.resumeFlag = false;
  175. resumeCbck1.resumeFlag = false;
  176. logStream << std::endl;
  177. }
  178. logStream << "Exiting." << std::endl;
  179. logStream.close();
  180. return(EXIT_SUCCESS);
  181. }