// -*- c++ -*- // Generated by assa-genesis //------------------------------------------------------------------------------ // $Id: reactor_test.cpp,v 1.7 2005/10/08 02:42:01 vlg Exp $ //------------------------------------------------------------------------------ // Reactor_Test.cpp //------------------------------------------------------------------------------ // Copyright (c) 2002,2005 by Vladislav Grinchenko // // Permission to use, copy, modify, and distribute this software // and its documentation for any purpose and without fee is hereby // granted, provided that the above copyright notice appear in all // copies. The author makes no representations about the suitability // of this software for any purpose. It is provided "as is" without // express or implied warranty. //------------------------------------------------------------------------------ // // Date : Fri Oct 25 14:14:13 2002 // //------------------------------------------------------------------------------ static const char help_msg[]= " \n" " NAME: \n" " \n" " reactor_test \n" " \n" " DESCRIPTION: \n" " \n" " A very simple test that illustrates basic Reactor usage. \n" " \n" " USAGE: \n" " \n" " shell> reactor_test [OPTIONS] \n" " \n" " OPTIONS: \n" " \n" " -D, --log-file NAME - Write debug to NAME file \n" " -d, --log-stdout - Write debug to standard output \n" " -z, --log-size NUM - Maximum size debug file can reach (dfl: is 10Mb) \n" " \n" " -m, --mask MASK - Mask (default: ALL = 0x7fffffff) \n" " \n" " -h, --help - Print this messag \n" " -v, --version - Print version number \n"; //------------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include using std::string; #include #include #include #include using namespace ASSA; /******************************************************************************* Class Std_In *******************************************************************************/ class Std_In : public EventHandler { public: Std_In () { trace_with_mask("Std_In::Std_In", REACTTRACE); set_id ("Std_In"); } ~Std_In () { trace_with_mask("Std_In::~Std_In",REACTTRACE); } virtual int handle_read (int); virtual int handle_timeout (TimerId); }; /* * When run from the script with HERE document as an input * construct, when shell reaches the end of the HERE documents, * it keeps sending 0x8 or \b (BS) control character. * I can't find any reference why it is doing so, but it * looks like this is the indication of the end of the stream. */ int Std_In:: handle_read (int /* fd */) { trace_with_mask("Std_In::handle_read",REACTTRACE); int ret; char c; ret = read (0, &c, 1); if (ret == 0 || c == '\b') { DL((REACT,"Found end-of-file\n")); return -1; } if (c != '\n') { DL((REACT,"read %c\n", c)); std::cout << "Read < " << c << " >\n"; MemDump::dump_to_log (APP, "Character received:", &c, 1); } return 0; } int Std_In:: handle_timeout (TimerId /* tid */) { trace_with_mask("Std_In::handle_timeout", REACTTRACE); DL((APP,"Timeout occured\n")); std::cout << "*** Timeout ***\n"; return 0; } /******************************************************************************* Class Reactor_Test *******************************************************************************/ class Reactor_Test : public GenServer, public Singleton { public: Reactor_Test (); virtual void init_service (); virtual void process_events (); }; /* Useful definitions */ #define REACTOR_TEST Reactor_Test::get_instance() #define REACTOR REACTOR_TEST->get_reactor() // Static declarations mandated by Singleton class ASSA_DECL_SINGLETON(Reactor_Test); Reactor_Test:: Reactor_Test () { // ---Configuration--- rm_opt ('f', "config-file" ); rm_opt ('n', "instance" ); rm_opt ('p', "port" ); // ---Process bookkeeping--- rm_opt ('b', "daemon" ); rm_opt ('l', "pidfile" ); rm_opt ('L', "ommit-pidfile"); /*--- * Disable all debugging *---*/ // m_mask = 0x0; m_log_file = "reactor_test.log"; } void Reactor_Test:: init_service () { trace("Reactor_Test::init_service"); Log::enable_timestamp (); DL((APP,"Service has been initialized\n")); } void Reactor_Test:: process_events () { trace("Reactor_Test::process_events"); static const char sep[]="*************************"; std::cout << "= Running reactor_test Test =\n"; Std_In myin; REACTOR->registerIOHandler (&myin, 0, READ_EVENT); std::cout << "Type something:\n"; std::cout << "Non-blocking poll ... "; DL((APP,"%s\n",sep)); DL((APP,"Non-blocking poll: \n")); DL((APP,"%s\n",sep)); TimeVal polltv; REACTOR->waitForEvents (&polltv); std::cout << " done.\n"; DL((APP,"%s\n",sep)); DL((APP,"Wait for 10 seconds with 5 timers: \n")); DL((APP,"%s\n",sep)); std::cout << "Waiting for 10 seconds ... type fast ... "; TimeVal onesec(1.0); REACTOR->registerTimerHandler (&myin, onesec, "01 sec"); TimeVal twosec(2.0); REACTOR->registerTimerHandler (&myin, twosec, "02 secs"); TimeVal threesec(3.0); REACTOR->registerTimerHandler (&myin, threesec, "03 secs"); TimeVal foursec(4.0); REACTOR->registerTimerHandler (&myin, foursec, "04 secs"); TimeVal fivesec(5.0); REACTOR->registerTimerHandler (&myin, fivesec, "05 secs"); TimeVal tensec(10.0); REACTOR->registerTimerHandler (&myin, tensec, "10 secs"); while (tensec != TimeVal::zeroTime()) { REACTOR->waitForEvents (&tensec); } std::cout << " done.\n" << "Remaining time " << double(tensec) << " secs.\n"; REACTOR->stopReactor (); DL((APP,"Service stopped!\n")); } int main (int argc, char* argv[]) { static const char release[] = "VERSION"; int patch_level = 0; REACTOR_TEST->set_version (release, patch_level); REACTOR_TEST->set_author ("Vladislav Grinchenko"); REACTOR_TEST->set_flags (GenServer::RMLOG); REACTOR_TEST->init (&argc, argv, help_msg); REACTOR_TEST->init_service (); REACTOR_TEST->process_events (); return REACTOR_TEST->get_exit_value (); }