// -*- c++ -*- // Generated by assa-genesis //------------------------------------------------------------------------------ // $Id: genserver_test.cpp,v 1.7 2006/07/20 02:30:56 vlg Exp $ //------------------------------------------------------------------------------ // genserver_test.cpp //------------------------------------------------------------------------------ // // Author : Vladislav Grinchenko // Date : Tue Dec 25 22:55:53 2001 //------------------------------------------------------------------------------ static const char help_msg[]= " \n" " NAME: \n" " genserver_test test program \n" " \n" " DESCRIPTION: \n" " \n" " Test illustrates basic usage of class GenServer. \n" " \n" " USAGE: \n" " \n" " shell> genserver_test [OPTIONS] \n" " \n" " OPTIONS: \n" " \n" " -b, --daemon - Run process as true UNIX daemon \n" " -l, --pidfile PATH - The process ID is written to the lockfile PATH \n" " instead of default ~/.{procname}.pid \n" " -L, --no-pidfile - Do not create PID lockfile \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" " -m, --mask MASK - Mask (default: ALL = 0x7fffffff) \n" " -p, --port NAME - The tcp/ip port NAME (default - procname) \n" " -n, --instance NUM - Process instance NUM (default - none) \n" " -f, --config-file NAME - Alternative configuration file NAME \n" " -h, --help - Print this messag \n" " -v, --version - Print version number \n"; //------------------------------------------------------------------------------ #include // kill(3) #include // kill(3) #if defined (WIN32) # include #endif #include #include using std::string; #include "assa/GenServer.h" #include "assa/Singleton.h" #include "assa/TimeVal.h" using namespace ASSA; class GSTest : public GenServer, public Singleton { public: /// Class Singleton requres a default constructor GSTest (); // Inherited from EventHandler virtual int handle_timeout (TimerId tid_); // Inherited from GenServer virtual void init_service (); virtual void process_events (); virtual void fatal_signal_hook (); private: // An example of processing positional arguments virtual void pos_arg (const char* arg_); private: u_int m_pos_arg_count; // Number of pos. arguments processed vector m_pargs; // Positional arguments int m_exit_value; // Return status of the process }; // Useful defines // #define SERVER GSTest::get_instance() #define REACTOR SERVER->get_reactor() // Static declarations mandated by Singleton class // ASSA_DECL_SINGLETON(GSTest); /******************************************************************************* Member functions *******************************************************************************/ GSTest::GSTest () : m_pos_arg_count (0), m_exit_value (0) { m_log_file = "genserver_test.log"; } void GSTest:: fatal_signal_hook () { trace("GSTest::fatal_signal_hook"); /* * Execute application-specific cleanup here */ DL((TRACE, "Stopping the service ...\n")); stop_service (); } void GSTest::pos_arg (const char* arg_) { trace("GSTest::pos_arg"); m_pargs.push_back (arg_); m_pos_arg_count++; } void GSTest:: init_service () { trace("GSTest::init_service"); Log::disable_timestamp (); TimeVal tv (5); // Terminate service in 5 seconds REACTOR->registerTimerHandler (this, tv); DL((APP,"Service has been initialized\n")); } int GSTest:: handle_timeout (TimerId tid_) { trace("GSTest::handle_timeout"); DL((APP,"5 seconds timer expired\n")); // // Testing signal handling: send myself SIGHUP // DL((APP,"Sending myself a SIGTERM signal\n")); pid_t mypid = ::getpid (); #if !defined (WIN32) if (::kill (mypid, SIGTERM) != 0) { EL((ASSA::ASSAERR,"failed: kill(self,SIGNUP)\n")); ::exit (1); } #else int ret; HANDLE hProc = OpenProcess(1, 0, mypid); ret = TerminateProcess(hProc, 0); CloseHandle(hProc); #endif return 0; } void GSTest:: process_events () { trace("GSTest::process_events"); if (m_pargs.size ()) { DL((TRACE,"Positional arguments:\n")); for (size_t i = 0; i < m_pargs.size (); i++) { DL((TRACE,"[%d] = \"%s\"\n", i, m_pargs[i].c_str ())); } } TimeVal tv_delay (2*60); // wating for two minutes TimeVal tv_two_secs; DL((TRACE, "Going to sleep for %d seconds ...\n", tv_delay.sec ())); DL((TRACE, "Kill with 'kill %d' to test signal handling\n", getpid())); while (service_is_active ()) { tv_two_secs = 2.0; get_reactor ()->waitForEvents (&tv_two_secs); tv_delay -= 2.0; if (tv_delay == TimeVal::zeroTime ()) { break; } } DL((TRACE,"Woken up! Exiting...\n")); } void dump_env (void) { DL((TRACE,"Process name.......[%s]\n", SERVER->get_proc_name().c_str())); DL((TRACE,"Command line name..[%s]\n", SERVER->get_cmdline_name().c_str())); DL((TRACE,"Std config name....[%s]\n", SERVER->get_default_config_file ().c_str())); DL((TRACE,"Alt config name....[%s]\n", SERVER->get_config_file().c_str())); } int main (int argc, char* argv[]) { static const char release[] = "1.0"; int patch_level = 0; register int i; std::cout << "= Running genserver_test Test =\n"; DL((TRACE,"Initial command-line arguments:\n")); for (i = 0; argv[i]; i++) { DL((TRACE,"[%d] - [%s], addr 0X%x\n", i, argv[i], (void*)argv[i])); } SERVER->set_version (release, patch_level); SERVER->set_author ("Vladislav Grinchenko"); SERVER->set_flags (GenServer::RMLOG); SERVER->init (&argc, argv, help_msg); for (i = 0; argv [i]; i++) { DL((TRACE,"[%d] - [%s], addr 0X%x\n", i, argv [i], (void*)argv [i])); } SERVER->init_service (); dump_env (); SERVER->process_events (); if (SERVER->get_exit_value () == 0) { std::cout << "Test passed\n"; } else { std::cout << "Test failed\n"; } return SERVER->get_exit_value (); }