#include <GenServer.h>
Inheritance diagram for ASSA::GenServer:
Public Types | |
enum | LogFlag { KEEPLOG, RMLOG } |
Public Member Functions | |
GenServer () | |
Constructor. | |
virtual | ~GenServer () |
Destructor. | |
virtual void | init (int *argc, char *argv[], const char *help_info) |
Provide an entry point into the service and perfom initialization of the service. | |
virtual int | fini (void) |
This is an iterface function corresponding to the object moving back into IDLE state. | |
virtual int | suspend (void) |
Temporarily suspend the execution of a service. | |
virtual int | resume (void) |
Resume execution of a service. | |
virtual void | init_service ()=0 |
Interface function provided for derived classes as a place to initialize specifics of derived server. | |
virtual void | process_events ()=0 |
Interface function provided for derived classes as the main entry for data processing. | |
virtual void | fatal_signal_hook () |
Hook for derived class to do addition clean-up when terminating signal is delivered by OS. | |
int | handle_signal (int signum_) |
Handle fatal signals. | |
bool | service_is_active () |
Normally called by the main loop to find out whether 'graceful quit' flag had been raised, signaling that some application's component requested to end data processing. | |
void | stop_service () |
Inform server that it has to stop data processing, clean up and exit. | |
void | set_version (const string &release_, int revision_) |
Set Version and Revision number. | |
string | get_version () |
Obtain version information. | |
void | set_author (const string &author_) |
Set author's name. | |
void | set_flags (LogFlag logf_) |
New debug information is added to the old log file. | |
virtual void | display_help () |
List options and invocation syntax to stdout. | |
string | get_proc_name () |
Get name of process+instance_number. | |
void | set_proc_name (string proc_name_) |
Change process name. | |
string | get_cmdline_name () |
Get command-line process name. | |
string | get_default_config_file () |
Get default configuration file name: $HOME/. | |
string | get_config_file () |
Get alternative configuration file name. | |
string | get_port () |
Return assumed name of the listening port. | |
void | set_port (string port_) |
Set listening port name. | |
SigHandlers & | get_sig_manager () |
Obtain reference to the Signal Manager, class SigHandls. | |
Reactor * | get_reactor () |
Obtain reference to the Reactor. | |
int | get_exit_value () const |
Retrieve exit value of the process. | |
Static Public Member Functions | |
static bool | become_daemon () |
Become a daemon process. | |
Protected Member Functions | |
void | set_exit_value (int v_) |
Set exit value of the process. This value is returned to the shell. | |
Protected Attributes | |
string | m_proc_name |
process name (considering instance_number) | |
string | m_cmdline_name |
process name as appeared on command line | |
string | m_port |
listening port name | |
string | m_default_config_file |
standard configuration file name | |
string | m_config_file |
alternative configuration file name | |
u_int | m_log_size |
Max size of the log file. | |
int | m_instance |
Process instance. | |
string | m_log_file |
Full pathname of debug file. | |
string | m_with_log_server |
If 'yes', send log messages to the log server. | |
string | m_log_server |
Log server, assa-logd, address (port@host). | |
long | m_mask |
Debug file mask to filter debug/error messages. | |
bool | m_graceful_quit |
Flag that indicates wheather server outgh to stop and exit. | |
SigHandlers | m_sig_dispatcher |
Signal handlers dispatcher. | |
SIGPOLLHandler | m_sig_poll |
Function that swallows SIGPOLL calls. | |
Reactor | m_reactor |
GenServer object has its very own personal Reactor object. | |
string | m_version |
Software version. | |
int | m_revision |
Software revision (patch) level. | |
string | m_author |
Author's name. | |
const char * | m_help_msg |
Help information. | |
LogFlag | m_log_flag |
Log file initialization flag. If RM_LOG, remove old log file. | |
string | m_log_stdout |
If 'yes', redirects all logging messages to std::cerr. | |
string | m_daemon |
Daemon option flag. If 'yes', become a UNIX daemon process. | |
string | m_ommit_pidfile |
If 'yes', skip PID file locking creation/locking step. | |
int | m_log_level |
Logging level - an integer number that incrementally increases verbosity of the looing messages. | |
PidFileLock | m_pidfile_lock |
PID File lock. | |
string | m_pidfile |
PID File lock path name. | |
bool | m_help_flag |
Help option flag. | |
bool | m_version_flag |
Version option flag. | |
int | m_exit_value |
Exit value of the process. | |
Private Member Functions | |
GenServer (const GenServer &) | |
No cloning. | |
GenServer & | operator= (const GenServer &) |
void | init_internals () |
Initialize internals. |
Definition at line 59 of file GenServer.h.
|
Definition at line 66 of file GenServer.h.
|
|
Constructor.
Corresponds to the object entering the Definition at line 56 of file GenServer.cpp. References ASSA::CmdLineOpts::add_flag_opt(), ASSA::CmdLineOpts::add_opt(), m_config_file, m_daemon, m_help_flag, m_instance, m_log_file, m_log_level, m_log_server, m_log_size, m_log_stdout, m_mask, m_ommit_pidfile, m_pidfile, m_port, m_version_flag, and m_with_log_server. 00056 : 00057 m_log_size (10485760), // 10 Mb 00058 m_instance (-1), 00059 m_with_log_server ("no"), 00060 m_log_server ("assalogd@"), 00061 m_mask (ALL), 00062 m_graceful_quit (false), 00063 m_version ("unknown"), 00064 m_revision (0), 00065 m_author ("John Doe"), 00066 m_help_msg ("No help available"), 00067 m_log_flag (KEEPLOG), 00068 m_log_stdout ("no"), 00069 m_daemon ("no"), 00070 m_ommit_pidfile ("no"), 00071 m_log_level (-1), 00072 m_help_flag (false), 00073 m_version_flag (false), 00074 m_exit_value (0) 00075 { 00076 add_flag_opt ('h', "help", &m_help_flag); 00077 add_flag_opt ('v', "version", &m_version_flag); 00078 00079 add_opt ('d', "log-stdout", &m_log_stdout); 00080 add_opt ('b', "daemon", &m_daemon); 00081 add_opt ('L', "ommit-pidfile", &m_ommit_pidfile); 00082 add_opt ('s', "with-log-server", &m_with_log_server); 00083 add_opt ('m', "mask", &m_mask); 00084 add_opt ('D', "log-file", &m_log_file); 00085 add_opt ('f', "config-file", &m_config_file); 00086 add_opt ('n', "instance", &m_instance); 00087 add_opt ('p', "port", &m_port); 00088 add_opt ('z', "log-size", &m_log_size); 00089 add_opt ('l', "pidfile", &m_pidfile); 00090 add_opt ('S', "log-server", &m_log_server); 00091 add_opt ('c', "log-level", &m_log_level); 00092 00095 char hn[64]; 00096 ::gethostname (hn, sizeof (hn)-1); 00097 m_log_server += hn; 00098 }
|
|
Destructor.
Definition at line 81 of file GenServer.h.
|
|
No cloning.
|
|
Become a daemon process.
Definition at line 306 of file GenServer.cpp. References ASSA::Fork::IGNORE_STATUS, ASSA::Fork::isChild(), and ASSA::Fork::LEAVE_ALONE. Referenced by init(). 00307 { 00308 #if defined(WIN32) 00309 return true; 00310 #else 00311 Fork f (Fork::LEAVE_ALONE, Fork::IGNORE_STATUS); 00312 00313 if (!f.isChild ()) { // parent exits 00314 exit (0); 00315 } 00316 00317 int size = 1024; 00318 int i = 0; 00319 pid_t nullfd; 00320 00321 for (i = 0; i < size; i++) { 00322 (void) close (i); 00323 } 00324 00325 nullfd = open ("/dev/null", O_WRONLY | O_CREAT, 0666); 00326 if (nullfd == -1) { 00327 syslog (LOG_ERR,"failed to open \"/dev/null\""); 00328 return false; 00329 } 00330 00331 (void) dup2 (nullfd, 1); 00332 (void) dup2 (nullfd, 2); 00333 (void) close (nullfd); 00334 00335 if ( setsid() == -1 ) { 00336 syslog (LOG_ERR,"setsid() failed"); 00337 return false; 00338 } 00339 00340 /*--- 00341 Changing to root directory would be the right thing to do for a 00342 server (so that it wouldn't possibly depend on any mounted file 00343 systems. But, in practice, it might cause a lot of problems. 00344 ---*/ 00345 #if 0 00346 if ( chdir("/") == -1 ) { 00347 return false; 00348 } 00349 #endif 00350 return (true); 00351 00352 #endif // defined(WIN32) 00353 }
|
|
List options and invocation syntax to stdout.
Definition at line 375 of file GenServer.h. References ASSA::endl(), m_author, and m_help_msg. Referenced by init(). 00376 { 00377 std::cout << m_help_msg << '\n' 00378 << "Written by " << m_author << "\n" << std::endl; 00379 }
|
|
Hook for derived class to do addition clean-up when terminating signal is delivered by OS. Note that signal handling is provided by default and no additional intervention is necessary. Use this method only to enhance it. Definition at line 135 of file GenServer.h. Referenced by handle_signal().
|
|
This is an iterface function corresponding to the object moving back into IDLE state. Derived class is expected to perform actions that terminate execution of the service. Definition at line 107 of file GenServer.h.
|
|
Get command-line process name.
Definition at line 190 of file GenServer.h. References m_cmdline_name. Referenced by init_internals(). 00190 { return m_cmdline_name; }
|
|
Get alternative configuration file name. This name is specified as command-line argument '-f' Definition at line 203 of file GenServer.h. References m_config_file. 00203 { return m_config_file; }
|
|
Get default configuration file name: $HOME/. {command_line_name}.cfg If you want your configuration file name to be different, change the value of m_std_config_name in derived class Definition at line 198 of file GenServer.h. References m_default_config_file. 00198 { return m_default_config_file; }
|
|
Retrieve exit value of the process.
Definition at line 227 of file GenServer.h. References m_exit_value. 00227 { return m_exit_value; }
|
|
Return assumed name of the listening port.
Definition at line 206 of file GenServer.h. References m_port. 00206 { return m_port; }
|
|
Get name of process+instance_number.
Definition at line 182 of file GenServer.h. References m_proc_name. 00182 { return m_proc_name; }
|
|
Obtain reference to the Reactor.
Definition at line 221 of file GenServer.h. References m_reactor. Referenced by handle_signal(). 00221 { return &m_reactor; }
|
|
Obtain reference to the Signal Manager, class SigHandls.
Definition at line 216 of file GenServer.h. References m_sig_dispatcher. 00216 { return m_sig_dispatcher; }
|
|
Obtain version information.
Definition at line 366 of file GenServer.h. References ASSA::ends(), m_revision, and m_version. Referenced by init(). 00367 { 00368 std::ostringstream v; 00369 v << "Version: " << m_version << " Revision: " << m_revision << std::ends; 00370 return (v.str ()); 00371 }
|
|
Handle fatal signals. Hook (e.g. fatalSignalHook) is provided if derived class needs extra work before falling dead. Reimplemented from ASSA::EventHandler. Definition at line 357 of file GenServer.cpp. References ASSA::APP, ASSA::Reactor::deactivate(), DL, ASSA::ends(), fatal_signal_hook(), get_reactor(), m_graceful_quit, and trace. 00358 { 00359 trace("GenServer::handle_signal"); 00360 std::ostringstream m; 00361 00362 switch (signum_) 00363 { 00364 case SIGTERM: m << "SIGTERM signal caugth. "; break; 00365 case SIGINT: m << "SIGINT signal caugth. "; break; 00366 default: m << "Unexpected signal caugth."; 00367 } 00368 m << "Signal # " << signum_ << std::ends; 00369 DL((APP,"%s\n", m.str ().c_str () )); 00370 DL((APP,"Initiating shutdown sequence...\n")); 00371 00372 fatal_signal_hook (); 00373 00374 DL((APP, "Shutdown sequence completed - Exiting !\n")); 00375 00376 /* Calling stop_service () triggers a call to Reactor::stopReactor() 00377 with subsequent call to Reactor::removeIOHandler() and then 00378 EventHandler::handle_close(). If EventHandler is in the middle 00379 of the *slow* system call such as read(2), handle_close() will 00380 destry EventHandler, and after cotrol is returned from 00381 GenServer::handle_signal(), *slow* system call is restarted 00382 and proceeds to operate on the memory that has been deleted already. 00383 00384 Calling Reactor::deactivate() instead delays memory release. 00385 */ 00386 get_reactor()->deactivate (); 00387 m_graceful_quit = true; 00388 00389 return 0; 00390 }
|
|
Provide an entry point into the service and perfom initialization of the service. Open log file and log startup options. Process standard command-line arguments. Following signals are handled in uniform manner: SIGHUP, SIGPIPE, SIGCHLD, SIGCLD, SIGALRM, SIGINT, SIGPOLL, SIGTERM. This function corresponds to the object moving from IDLE to RUNNING state as result of service initialization, or reconfiguration of the service and remaining in RUNNING state.
Definition at line 107 of file GenServer.cpp. References ASSA_DIR_SEPARATOR, become_daemon(), display_help(), ASSA::endl(), ASSA::CmdLineOpts::get_opt_error(), get_version(), m_author, m_cmdline_name, m_daemon, m_help_flag, m_help_msg, m_instance, m_proc_name, m_version_flag, and ASSA::CmdLineOpts::parse_args(). 00108 { 00109 char* cp = argv [0]; 00110 m_help_msg = ht_; 00111 00116 if (strchr(cp, ASSA_DIR_SEPARATOR)) { 00117 cp += strlen(argv[0]); // position at the end 00118 while (*cp-- != ASSA_DIR_SEPARATOR) { 00119 ; 00120 } 00121 cp += 2; 00122 } 00123 00124 #if defined (WIN32) // get rid of '.exe' 00125 char* extidx = cp; 00126 while (*extidx) { 00127 if (*extidx == '.') { 00128 *extidx = '\0'; 00129 break; 00130 } 00131 extidx++; 00132 } 00133 #endif 00134 m_cmdline_name = cp; 00135 00136 if (!parse_args ((const char **)argv)) { 00137 std::cerr << "Error in arguments: " << get_opt_error () << std::endl; 00138 std::cerr << "Try '" << argv[0] << " --help' for details.\n"; 00139 exit (1); 00140 } 00141 if (m_help_flag) { 00142 display_help (); 00143 exit (0); 00144 } 00145 if (m_version_flag) { 00146 std::cerr << '\n' << argv[0] << " " << get_version () << '\n' << '\n' 00147 << "Written by " << m_author << "\n\n"; 00148 exit (0); 00149 } 00150 if (m_daemon == "yes") { 00151 assert(become_daemon ()); 00152 } 00155 char instbuf[16]; // INT_MAX [-]2147483647 00156 sprintf(instbuf, "%d", m_instance); 00157 00158 if (m_proc_name.length() == 0) { 00159 m_proc_name = m_cmdline_name; 00160 00161 if (m_instance != -1) { 00162 m_proc_name += instbuf; 00163 } 00164 } 00165 if (m_port.length() == 0) { 00166 m_port = m_proc_name; 00167 } 00168 00169 #if !defined(WIN32) 00170 00173 SigAction ignore_act( SIG_IGN ); 00174 00182 ignore_act.register_action( SIGHUP ); 00183 00184 ignore_act.register_action( SIGPIPE ); 00185 ignore_act.register_action( SIGCHLD ); 00186 #if !(defined (__FreeBSD__) || defined(__FreeBSD_kernel__) \ 00187 || defined (__NetBSD__)) 00188 ignore_act.register_action( SIGCLD ); 00189 #endif 00190 ignore_act.register_action( SIGALRM ); 00191 00196 m_sig_dispatcher.install ( ASSAIOSIG, &m_sig_poll ); 00197 00204 m_sig_dispatcher.install ( SIGINT, (EventHandler*) this ); 00205 00212 m_sig_dispatcher.install ( SIGTERM, (EventHandler*) this ); 00213 00214 #endif // !defined(WIN32) 00215 00218 init_internals (); 00219 }
|
|
Initialize internals. Set standard configuration file name. For POSIX systems, it is $HOME/.procname. For Win32, it is $cwd/procname.ini. Remove existing log file if requested. Unlinking /dev/null character device and replacing it with a regular file leads to the system crash during consecutive reboots. See also assa/FileLogger.cpp. Open logging facility: --log-stdout="yes" takes precedence over --with-log-server="yes" which takes precedence over --log-file=/path/to/log Definition at line 223 of file GenServer.cpp. References get_cmdline_name(), m_default_config_file, m_log_file, m_log_flag, m_log_stdout, RMLOG, and ASSA::Utils::strenv(). 00224 { 00225 static const char self[] = "GenServer::init_internals"; 00226 00231 #if defined (WIN32) 00232 m_default_config_file = this->get_cmdline_name () + ".ini"; 00233 #else 00234 m_default_config_file = "$HOME/." + this->get_cmdline_name (); 00235 m_default_config_file = Utils::strenv (m_default_config_file.c_str ()); 00236 #endif 00237 00243 if (m_log_flag == RMLOG && m_log_stdout == "no") { 00244 struct stat fst; 00245 if (::stat (m_log_file.c_str(), &fst) == 0) { 00246 if (S_ISREG (fst.st_mode)) { 00247 ::unlink (m_log_file.c_str()); 00248 } 00249 } 00250 } 00251 00259 Log::set_app_name (get_proc_name ()); 00260 00261 if (m_log_stdout == "yes") { 00262 Log::open_log_stdout (m_mask); 00263 } 00264 else { 00265 if (m_with_log_server == "yes") { 00266 Log::open_log_server (m_log_server, 00267 m_log_file.c_str(), 00268 get_reactor (), 00269 m_mask, 00270 m_log_size) ; 00271 } 00272 else { 00273 Log::open_log_file (m_log_file.c_str(), m_mask, m_log_size); 00274 } 00275 } 00276 00277 trace(self); 00278 00279 if (m_ommit_pidfile == "no") { 00280 if (m_pidfile.size () == 0) { 00281 m_pidfile = "~/." + m_proc_name + ".pid"; 00282 } 00283 if (! m_pidfile_lock.lock (m_pidfile)) { 00284 DL((ASSAERR,"Failed to lock PID file: %s\n", 00285 m_pidfile_lock.get_error_msg ())); 00286 exit (1); 00287 } 00288 } 00289 00290 DL((APP,"\n" )); 00291 DL((APP,"========================================================\n")); 00292 DL((APP,"|| Server configuration settings ||\n")); 00293 DL((APP,"========================================================\n")); 00294 DL((APP," cmd_line_name = '%s'\n", m_cmdline_name.c_str() )); 00295 DL((APP," name = '%s'\n", m_proc_name.c_str() )); 00296 DL((APP," default config file = '%s'\n", m_default_config_file.c_str())); 00297 DL((APP," config file = '%s'\n", m_config_file.c_str() )); 00298 DL((APP," mask = 0x%X\n", m_mask )); 00299 dump (); 00300 DL((APP,"========================================================\n")); 00301 DL((APP,"\n")); 00302 }
|
|
Interface function provided for derived classes as a place to initialize specifics of derived server.
|
|
|
|
Interface function provided for derived classes as the main entry for data processing. This is the place to implement main event loop. |
|
Resume execution of a service. Corresponds to the process returning back to RUNNING state from SUSPENDED state. Definition at line 117 of file GenServer.h.
|
|
Normally called by the main loop to find out whether 'graceful quit' flag had been raised, signaling that some application's component requested to end data processing.
Definition at line 149 of file GenServer.h. References m_graceful_quit. 00149 { return (!m_graceful_quit); }
|
|
Set author's name.
Definition at line 359 of file GenServer.h. References m_author. 00360 { 00361 m_author = author_; 00362 }
|
|
Set exit value of the process. This value is returned to the shell.
Definition at line 231 of file GenServer.h. References m_exit_value. 00231 { m_exit_value = v_; }
|
|
New debug information is added to the old log file. To erase old log file, set flag to RMLOG.
Definition at line 176 of file GenServer.h. References m_log_flag. 00176 { m_log_flag = logf_; }
|
|
Set listening port name.
Definition at line 211 of file GenServer.h. References m_port. 00211 { m_port = port_; }
|
|
Change process name.
Definition at line 187 of file GenServer.h. References m_proc_name. 00187 { m_proc_name = proc_name_; }
|
|
Set Version and Revision number.
Definition at line 351 of file GenServer.h. References m_revision, and m_version. 00352 { 00353 m_version = release_; 00354 m_revision = revision_; 00355 }
|
|
Inform server that it has to stop data processing, clean up and exit. This method will also stop internal Reactor. Definition at line 343 of file GenServer.h. References ASSA::Reactor::deactivate(), m_graceful_quit, and m_reactor. 00344 { 00345 m_graceful_quit = true; 00346 m_reactor.deactivate (); 00347 }
|
|
Temporarily suspend the execution of a service. Corresponds to process leaving RUNNING state and entering SUSPENDED state. Definition at line 112 of file GenServer.h.
|
|
Author's name.
Definition at line 289 of file GenServer.h. Referenced by display_help(), init(), and set_author(). |
|
process name as appeared on command line
Definition at line 238 of file GenServer.h. Referenced by get_cmdline_name(), and init(). |
|
alternative configuration file name
Definition at line 247 of file GenServer.h. Referenced by GenServer(), and get_config_file(). |
|
Daemon option flag. If 'yes', become a UNIX daemon process.
Definition at line 301 of file GenServer.h. Referenced by GenServer(), and init(). |
|
standard configuration file name
Definition at line 244 of file GenServer.h. Referenced by get_default_config_file(), and init_internals(). |
|
Exit value of the process.
Definition at line 329 of file GenServer.h. Referenced by get_exit_value(), and set_exit_value(). |
|
Flag that indicates wheather server outgh to stop and exit.
Definition at line 269 of file GenServer.h. Referenced by handle_signal(), service_is_active(), and stop_service(). |
|
Help option flag. If true, [-h, --help] option is being specified on command line. Definition at line 321 of file GenServer.h. Referenced by GenServer(), and init(). |
|
Help information.
Definition at line 292 of file GenServer.h. Referenced by display_help(), and init(). |
|
Process instance.
Definition at line 253 of file GenServer.h. Referenced by GenServer(), and init(). |
|
Full pathname of debug file.
Definition at line 256 of file GenServer.h. Referenced by GenServer(), and init_internals(). |
|
Log file initialization flag. If RM_LOG, remove old log file.
Definition at line 295 of file GenServer.h. Referenced by init_internals(), and set_flags(). |
|
Logging level - an integer number that incrementally increases verbosity of the looing messages. The exact meaning of each level is application-specific. Definition at line 310 of file GenServer.h. Referenced by GenServer(). |
|
Log server, assa-logd, address (port@host).
Definition at line 263 of file GenServer.h. Referenced by GenServer(). |
|
Max size of the log file.
Definition at line 250 of file GenServer.h. Referenced by GenServer(). |
|
If 'yes', redirects all logging messages to std::cerr.
Definition at line 298 of file GenServer.h. Referenced by GenServer(), and init_internals(). |
|
Debug file mask to filter debug/error messages.
Definition at line 266 of file GenServer.h. Referenced by GenServer(). |
|
If 'yes', skip PID file locking creation/locking step.
Definition at line 304 of file GenServer.h. Referenced by GenServer(). |
|
PID File lock path name.
Definition at line 316 of file GenServer.h. Referenced by GenServer(). |
|
PID File lock.
Definition at line 313 of file GenServer.h. |
|
listening port name
Definition at line 241 of file GenServer.h. Referenced by GenServer(), get_port(), and set_port(). |
|
process name (considering instance_number)
Definition at line 235 of file GenServer.h. Referenced by get_proc_name(), init(), and set_proc_name(). |
|
GenServer object has its very own personal Reactor object.
Definition at line 280 of file GenServer.h. Referenced by get_reactor(), and stop_service(). |
|
Software revision (patch) level.
Definition at line 286 of file GenServer.h. Referenced by get_version(), and set_version(). |
|
Signal handlers dispatcher.
Definition at line 273 of file GenServer.h. Referenced by get_sig_manager(). |
|
Function that swallows SIGPOLL calls.
Definition at line 276 of file GenServer.h. |
|
Software version.
Definition at line 283 of file GenServer.h. Referenced by get_version(), and set_version(). |
|
Version option flag. If true, [-v, --version] options is being specified on command line. Definition at line 326 of file GenServer.h. Referenced by GenServer(), and init(). |
|
If 'yes', send log messages to the log server.
Definition at line 259 of file GenServer.h. Referenced by GenServer(). |