123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- // \file serviceProgram.cpp
- //
- // Service program for testing CodeDweller::Service.
- //
- // Usage:
- //
- // serviceProgram <logFileName> <message>
- //
- // where <logFileName> is the name of a file to write to, and
- // <message> is the message callback timeout to test. <message> can
- // be Pause, Resume, or Stop. If <message> is anything else, then
- // <message> is ignored.
- //
- // This program:
- //
- // 1) Sets the callback timeout to 500 ms.
- //
- // 2) Registers callbacks for various messages. Each callback
- // normaly sleeps for 400 ms, which is less than the timeout.
- // However, if <message> is present, the callback for the specified
- // message sleeps for 600 ms. This should cause the service to
- // exit.
- //
- // 3) While the stop flag is false, outputs the status of all flags
- // to the log file every 2 seconds, and clears all flags.
- //
- // 4) After Stop is received, output the status of all flags, and
- // exit.
- //
- // 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
- //==============================================================================
-
- /////////////////////////////////////////////////////////////////////////////
- // Configuration ////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
-
- // How long to sleep between iterations. This value is longer for
- // Windows because the sc command takes about 0.7 s to execute on the
- // development/text Windows 7 system.
- #ifdef WIN32
- const int delayTime_ms = 2700;
- #else
- const int delayTime_ms = 2000;
- #endif
-
- // Callback timeout time.
- const int timeoutTime_ms = 500;
-
- // How long the callback takes to not exceed the timeout.
- const int shortSleepTime_ms = 400;
-
- // How long the callback takes to exceed the timeout.
- const int longSleepTime_ms = 600;
-
- /////////////////////////////////////////////////////////////////////////////
- // End of configuration /////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
-
- #include <cstdlib>
- #include <fstream>
- #include <thread>
-
- #include "CodeDweller/service.hpp"
-
- /// Callback functor for Pause message.
- class PauseCallback : public CodeDweller::Service::Callback {
-
- public:
-
- PauseCallback() : pauseFlag(false) {}
-
- // Total sleep time for all Pause callbacks should be less than 1000
- // ms. Reason: The while loop below sleeps for two seconds, and the
- // buildAndRun script sends the message one second into the sleep.
- // The callbacks must be completed before the main loop checks the
- // pauseFlag value.
- //
- // This applies to ResumeCallback and StopCallback.
- int sleepTime_ms = shortSleepTime_ms;
-
- bool pauseFlag;
-
- void operator()() {
- std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime_ms));
- pauseFlag = true;
- }
-
- };
-
- PauseCallback pauseCbck;
- PauseCallback pauseCbck1;
-
- /// Callback functor for Resume message.
- class ResumeCallback : public CodeDweller::Service::Callback {
-
- public:
-
- ResumeCallback() : resumeFlag(false) {}
-
- int sleepTime_ms = shortSleepTime_ms;
-
- bool resumeFlag;
-
- void operator()() {
- std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime_ms));
- resumeFlag = true;
- }
-
- };
-
- ResumeCallback resumeCbck;
- ResumeCallback resumeCbck1;
-
- /// Callback functor for Stop message.
- class StopCallback : public CodeDweller::Service::Callback {
-
- public:
-
- StopCallback() : stopFlag(false) {}
-
- int sleepTime_ms = shortSleepTime_ms;
-
- bool stopFlag;
-
- void operator()() {
- std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime_ms));
- stopFlag = true;
- }
-
- };
-
- StopCallback stopCbck;
- StopCallback stopCbck1;
- StopCallback notStopCbck;
-
- int CodeDweller::Service::run() {
-
- // Set the callback timeout to the default.
- CodeDweller::Service::setStopCallbackTimeout_ms(timeoutTime_ms);
-
- // Get the log file name.
- auto arguments = CodeDweller::Service::arguments();
-
- if (arguments.size() == 3) {
- // Increase the time it takes for a callback to execute.
- if (arguments[2] == "Pause") {
- pauseCbck.sleepTime_ms = longSleepTime_ms;
- pauseCbck1.sleepTime_ms = longSleepTime_ms;
- } else if (arguments[2] == "Resume") {
- resumeCbck.sleepTime_ms = longSleepTime_ms;
- resumeCbck1.sleepTime_ms = longSleepTime_ms;
- } else if (arguments[2] == "Stop") {
- stopCbck.sleepTime_ms = longSleepTime_ms;
- stopCbck1.sleepTime_ms = longSleepTime_ms;
- }
-
- }
- if ( (arguments.size() != 2) && (arguments.size() != 3) ) {
- return(EXIT_FAILURE);
- }
-
- // Get log file.
- std::ofstream logStream(arguments[1], std::fstream::app);
-
- // Register the callbacks.
- CodeDweller::Service::onPauseCall(pauseCbck);
- CodeDweller::Service::onPauseCall(pauseCbck1);
-
- CodeDweller::Service::onResumeCall(resumeCbck);
- CodeDweller::Service::onResumeCall(resumeCbck1);
-
- CodeDweller::Service::onStopCall(stopCbck);
- CodeDweller::Service::onStopCall(stopCbck1);
-
- while (!stopCbck.stopFlag) {
-
- logStream << "Sleeping 2 s...";
- logStream.flush();
- std::this_thread::sleep_for(std::chrono::milliseconds(delayTime_ms));
- logStream << "done." << std::endl;
-
- logStream << "receivedPause(): "
- << CodeDweller::Service::receivedPause() << std::endl;
- logStream << "receivedResume(): "
- << CodeDweller::Service::receivedResume() << std::endl;
- logStream << "receivedStop(): "
- << CodeDweller::Service::receivedStop() << std::endl;
-
- logStream << "Clearing all flags." << std::endl;
- CodeDweller::Service::clearReceivedPause();
- CodeDweller::Service::clearReceivedResume();
- CodeDweller::Service::clearReceivedStop();
-
- logStream << "receivedPause(): "
- << CodeDweller::Service::receivedPause() << std::endl;
- logStream << "receivedResume(): "
- << CodeDweller::Service::receivedResume() << std::endl;
- logStream << "receivedStop(): "
- << CodeDweller::Service::receivedStop() << std::endl;
-
- logStream << "pauseCbck.pauseFlag: " << pauseCbck.pauseFlag << std::endl;
- logStream << "pauseCbck1.pauseFlag: " << pauseCbck1.pauseFlag << std::endl;
- logStream << "resumeCbck.resumeFlag: " << resumeCbck.resumeFlag
- << std::endl;
- logStream << "resumeCbck1.resumeFlag: " << resumeCbck1.resumeFlag
- << std::endl;
- logStream << "stopCbck.stopFlag: " << stopCbck.stopFlag << std::endl;
- logStream << "stopCbck1.stopFlag: " << stopCbck1.stopFlag << std::endl;
- logStream << "notStopCbck.stopFlag: " << notStopCbck.stopFlag << std::endl;
-
- pauseCbck.pauseFlag = false;
- pauseCbck1.pauseFlag = false;
- resumeCbck.resumeFlag = false;
- resumeCbck1.resumeFlag = false;
-
- logStream << std::endl;
-
- }
-
- logStream << "Exiting." << std::endl;
-
- logStream.close();
-
- return(EXIT_SUCCESS);
- }
|