1.3. GenServer Introduction

GenServer is based on the idea of organizing your C++ application in such manner that would allow you to avoid global variables as discussed in B. Stroustrup's "The C++ Progamming Language" [BjarneStroustrup97]. GenServer is an encapsulation of the most commonly used characteristics of a UNIX application. To create the actual application, you start with deriving your application class from GenServer base class. We derive our application class, HelloWorld from base class GenServer. File HelloWorld.h holds the class declaration:

Example 1-1. Example of the application framework (header file)


// HelloWorld.h

021 #ifndef HelloWorld_H
022 #define HelloWorld_H
023 
024 
025 #ifdef HAVE_CONFIG_H
026 #    include "config.h"
027 #endif
028 #include <string>
029 using std::string;
030 
031 #include <assa/GenServer.h>
032 #include <assa/Singleton.h>
033 #include <assa/TimeVal.h>
034 
035 class HelloWorld :
036     public ASSA::GenServer,
037     public ASSA::Singleton<HelloWorld>
038 {
039 public:
040     HelloWorld ();
041 
042     virtual void initServer ();
043     virtual void processServer ();
044 
045     int  get_exit_value () const { return m_exit_value; }
046     void set_exit_value (int v_) { m_exit_value = v_;   }
047 
048 private:
049     int m_exit_value;     // Return status of the process
050 };
051 
052 
053 /* Useful definitions */
054 
055 #define HELLOWORLD  HelloWorld::getInstance()
056 #define REACTOR HELLOWORLD->getReactor()
057 
058 
059 #endif // HelloWorld_H

		

Example 1-2. Example of the application framework (constructor)


// HelloWorld.cpp

026 HelloWorld* ASSA::Singleton<HelloWorld>::m_instance;
027 ASSA::Destroyer<HelloWorld> ASSA::Singleton<HelloWorld>::m_destroyer;
028 
029 HelloWorld::
030 HelloWorld () :
031       m_exit_value (0)
032 {
033 
    ...
062     m_debug_mask = ASSA::APP | ASSA::ERROR;
063     m_log_file = "HelloWorld.log";
064 }
065 
		  

Example 1-3. Example of the log file, HelloWorld.log


[GenServer::initInternals] 
[GenServer::initInternals] ==================================================
[GenServer::initInternals] ||         Server configuration settings        ||
[GenServer::initInternals] ==================================================
[GenServer::initInternals]  cmd_line_name = 'HelloWorld'
[GenServer::initInternals]  name = 'HelloWorld'
[GenServer::initInternals]  std cfg fname = '/home/vlg/.gnome/HelloWorld'
[GenServer::initInternals]  alt cfg fname = ''
[GenServer::initInternals]  debug_mask = 0x22
[GenServer::initInternals] ==================================================
[GenServer::initInternals] 
[HelloWorld::initServer] Service has been initialized
[HelloWorld::processServer] Service stopped!
		

Log file shows that at some point initInternals() function of class GenServer was called to initialize base class internals. It also reported some basing configuration settings. Then initServer() function of class HelloWorld was called to initialize the program. At the end, processServer() function was called to perform data processing.

Example 1-4. Framework initialization


// From HelloWorld.cpp

067 void
068 HelloWorld::
069 initServer ()
070 {
071     trace("HelloWorld::initServer");
072 
073     //
074     // Insert initialization code here
075     //
076 
077     DL((ASSA::APP,"Service has been initialized\n"));
078 }
		

Function initServer() is the initialization code placeholder. Here you might want to open and parse your configuration file and initialize other components (such as mapping GUI mainwindow on the screen or, perhaps, opening listening socket as a TCP/IP server).

Example 1-5. Framework data processing


// From HelloWorld.cpp

079 
080 #include <iostream>
081 
082 void
083 HelloWorld::
084 processServer ()
085 {
086     trace("HelloWorld::processServer");
087 
088 //    while (!stopServer()) {
089 //        m_reactor.waitForEvents ();
090 //    }
091 //
092 
093     std::cout << "Hello, World!" << std::endl;
094 
095     // Shut the service down
096     m_reactor.stopReactor ();
097     DL((ASSA::APP,"Service stopped!\n"));
098 }
		

Function processServer() is where data processing activity of the program occurs. Both client and server applications would have some kind of an event loop here.