#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 57 of file GenServer.h.
|
Definition at line 64 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 }
|
|
Destructor.
Definition at line 79 of file GenServer.h.
|
|
No cloning.
|
|
Become a daemon process.
Definition at line 281 of file GenServer.cpp. References ASSA::Fork::IGNORE_STATUS, ASSA::Fork::isChild(), and ASSA::Fork::LEAVE_ALONE. Referenced by init(), and init_internals(). 00282 { 00283 Fork f (Fork::LEAVE_ALONE, Fork::IGNORE_STATUS); 00284 00285 if (!f.isChild ()) { // parent exits 00286 exit (0); 00287 } 00288 00289 int size = 1024; 00290 int i = 0; 00291 pid_t nullfd; 00292 00293 for (i = 0; i < size; i++) { 00294 (void) close (i); 00295 } 00296 00297 nullfd = open ("/dev/null", O_WRONLY | O_CREAT, 0666); 00298 if (nullfd == -1) { 00299 syslog (LOG_ERR,"failed to open \"/dev/null\""); 00300 return false; 00301 } 00302 00303 (void) dup2 (nullfd, 1); 00304 (void) dup2 (nullfd, 2); 00305 (void) close (nullfd); 00306 00307 if ( setsid() == -1 ) { 00308 syslog (LOG_ERR,"setsid() failed"); 00309 return false; 00310 } 00311 00312 /*--- 00313 Changing to root directory would be the right thing to do for a 00314 server (so that it wouldn't possibly depend on any mounted file 00315 systems. But, in practice, it might cause a lot of problems. 00316 ---*/ 00317 #if 0 00318 if ( chdir("/") == -1 ) { 00319 return false; 00320 } 00321 #endif 00322 return (true); 00323 }
|
|
List options and invocation syntax to stdout.
Definition at line 369 of file GenServer.h. References ASSA::endl(), m_author, and m_help_msg. Referenced by init(). 00370 { 00371 std::cout << m_help_msg << '\n' 00372 << "Written by " << m_author << "\n" << std::endl; 00373 }
|
|
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 133 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 105 of file GenServer.h.
|
|
Get command-line process name.
Definition at line 188 of file GenServer.h. References m_cmdline_name. Referenced by init_internals(). 00188 { return m_cmdline_name; }
|
|
Get alternative configuration file name. This name is specified as command-line argument '-f' Definition at line 201 of file GenServer.h. References m_config_file. 00201 { 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 196 of file GenServer.h. References m_default_config_file. 00196 { return m_default_config_file; }
|
|
Retrieve exit value of the process.
Definition at line 223 of file GenServer.h. References m_exit_value. 00223 { return m_exit_value; }
|
|
Return assumed name of the listening port.
Definition at line 204 of file GenServer.h. References m_port. 00204 { return m_port; }
|
|
Get name of process+instance_number.
Definition at line 180 of file GenServer.h. References m_proc_name. Referenced by init_internals(). 00180 { return m_proc_name; }
|
|
Obtain reference to the Reactor.
Definition at line 217 of file GenServer.h. References m_reactor. Referenced by handle_signal(), and init_internals(). 00217 { return &m_reactor; }
|
|
Obtain reference to the Signal Manager, class SigHandls.
Definition at line 213 of file GenServer.h. References m_sig_dispatcher. 00213 { return m_sig_dispatcher; }
|
|
Obtain version information.
Definition at line 360 of file GenServer.h. References ASSA::ends(), m_revision, and m_version. Referenced by init(). 00361 { 00362 std::ostringstream v; 00363 v << "Version: " << m_version << " Revision: " << m_revision << std::ends; 00364 return (v.str ()); 00365 }
|
|
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 327 of file GenServer.cpp. References ASSA::APP, ASSA::Reactor::deactivate(), DL, ASSA::ends(), fatal_signal_hook(), get_reactor(), m_graceful_quit, and trace. 00328 { 00329 trace("GenServer::handle_signal"); 00330 std::ostringstream m; 00331 00332 switch (signum_) 00333 { 00334 case SIGTERM: m << "SIGTERM signal caugth. "; break; 00335 case SIGINT: m << "SIGINT signal caugth. "; break; 00336 default: m << "Unexpected signal caugth."; 00337 } 00338 m << "Signal # " << signum_ << std::ends; 00339 DL((APP,"%s\n", m.str ().c_str () )); 00340 DL((APP,"Initiating shutdown sequence...\n")); 00341 00342 fatal_signal_hook (); 00343 00344 DL((APP, "Shutdown sequence completed - Exiting !\n")); 00345 00346 /* Calling stop_service () triggers a call to Reactor::stopReactor() 00347 with subsequent call to Reactor::removeIOHandler() and then 00348 EventHandler::handle_close(). If EventHandler is in the middle 00349 of the *slow* system call such as read(2), handle_close() will 00350 destry EventHandler, and after cotrol is returned from 00351 GenServer::handle_signal(), *slow* system call is restarted 00352 and proceeds to operate on the memory that has been deleted already. 00353 00354 Calling Reactor::deactivate() instead delays memory release. 00355 */ 00356 get_reactor()->deactivate (); 00357 m_graceful_quit = true; 00358 00359 return 0; 00360 }
|
|
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 101 of file GenServer.cpp. References 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(). 00102 { 00103 char* cp = argv [0]; 00104 m_help_msg = ht_; 00105 00110 if ( strchr(cp,'/') ) { 00111 cp += strlen(argv[0]); // position at the end 00112 while ( *cp-- != '/' ) ; 00113 cp += 2; 00114 } 00115 m_cmdline_name = cp; 00116 00117 if (!parse_args ((const char **)argv)) { 00118 std::cerr << "Error in arguments: " << get_opt_error () << std::endl; 00119 std::cerr << "Try '" << argv[0] << " --help' for details.\n"; 00120 exit (1); 00121 } 00122 if (m_help_flag) { 00123 display_help (); 00124 exit (0); 00125 } 00126 if (m_version_flag) { 00127 std::cerr << '\n' << argv[0] << " " << get_version () << '\n' << '\n' 00128 << "Written by " << m_author << "\n\n"; 00129 exit (0); 00130 } 00131 if (m_daemon == "yes") { 00132 assert(become_daemon ()); 00133 } 00136 char instbuf[16]; // INT_MAX [-]2147483647 00137 sprintf(instbuf, "%d", m_instance); 00138 00139 if (m_proc_name.length() == 0) { 00140 m_proc_name = m_cmdline_name; 00141 00142 if (m_instance != -1) { 00143 m_proc_name += instbuf; 00144 } 00145 } 00146 if (m_port.length() == 0) { 00147 m_port = m_proc_name; 00148 } 00149 00153 SigAction ignore_act( SIG_IGN ); 00154 00162 ignore_act.register_action( SIGHUP ); 00163 00164 ignore_act.register_action( SIGPIPE ); 00165 ignore_act.register_action( SIGCHLD ); 00166 #if !defined (__FreeBSD__) && !defined(__FreeBSD_kernel__) 00167 ignore_act.register_action( SIGCLD ); 00168 #endif 00169 ignore_act.register_action( SIGALRM ); 00170 00175 m_sig_dispatcher.install ( ASSAIOSIG, &m_sig_poll ); 00176 00183 m_sig_dispatcher.install ( SIGINT, (EventHandler*) this ); 00184 00191 m_sig_dispatcher.install ( SIGTERM, (EventHandler*) this ); 00192 00195 init_internals (); 00196 }
|
|
Initialize internals. Set standard configuration file name 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 200 of file GenServer.cpp. References ASSA::APP, become_daemon(), DL, ASSA::CmdLineOpts::dump(), ASSA::ERROR, get_cmdline_name(), ASSA::PidFileLock::get_error_msg(), get_proc_name(), get_reactor(), ASSA::PidFileLock::lock(), m_cmdline_name, m_config_file, m_default_config_file, m_log_file, m_log_flag, m_log_server, m_log_size, m_log_stdout, m_mask, m_ommit_pidfile, m_pidfile, m_pidfile_lock, m_proc_name, m_with_log_server, ASSA::Log::open_log_file(), ASSA::Log::open_log_server(), ASSA::Log::open_log_stdout(), RMLOG, ASSA::Log::set_app_name(), ASSA::Utils::strenv(), and trace. 00201 { 00202 static const char self[] = "GenServer::init_internals"; 00203 char* chp; 00204 00207 m_default_config_file = "$HOME/." + this->get_cmdline_name (); 00208 m_default_config_file = Utils::strenv (m_default_config_file.c_str ()); 00209 00215 if (m_log_flag == RMLOG && m_log_stdout == "no") { 00216 struct stat fst; 00217 if (::stat (m_log_file.c_str(), &fst) == 0) { 00218 if (S_ISREG (fst.st_mode)) { 00219 ::unlink (m_log_file.c_str()); 00220 } 00221 } 00222 } 00223 00230 char hn[64]; 00231 ::gethostname (hn, sizeof (hn)-1); 00232 m_log_server += hn; 00233 00234 Log::set_app_name (get_proc_name ()); 00235 00236 if (m_log_stdout == "yes") { 00237 Log::open_log_stdout (m_mask); 00238 } 00239 else { 00240 if (m_with_log_server == "yes") { 00241 Log::open_log_server (m_log_server, 00242 m_log_file.c_str(), 00243 get_reactor (), 00244 m_mask, 00245 m_log_size) ; 00246 } 00247 else { 00248 Log::open_log_file (m_log_file.c_str(), m_mask, m_log_size); 00249 } 00250 } 00251 00252 trace(self); 00253 00254 if (m_ommit_pidfile == "no") { 00255 if (m_pidfile.size () == 0) { 00256 m_pidfile = "~/." + m_proc_name + ".pid"; 00257 } 00258 if (! m_pidfile_lock.lock (m_pidfile)) { 00259 DL((ERROR,"Failed to lock PID file: %s\n", 00260 m_pidfile_lock.get_error_msg ())); 00261 exit (1); 00262 } 00263 } 00264 00265 DL((APP,"\n" )); 00266 DL((APP,"========================================================\n")); 00267 DL((APP,"|| Server configuration settings ||\n")); 00268 DL((APP,"========================================================\n")); 00269 DL((APP," cmd_line_name = '%s'\n", m_cmdline_name.c_str() )); 00270 DL((APP," name = '%s'\n", m_proc_name.c_str() )); 00271 DL((APP," default config file = '%s'\n", m_default_config_file.c_str())); 00272 DL((APP," config file = '%s'\n", m_config_file.c_str() )); 00273 DL((APP," mask = 0x%X\n", m_mask )); 00274 dump (); 00275 DL((APP,"========================================================\n")); 00276 DL((APP,"\n")); 00277 }
|
|
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 115 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 147 of file GenServer.h. References m_graceful_quit. 00147 { return (!m_graceful_quit); }
|
|
Set author's name.
Definition at line 353 of file GenServer.h. References m_author. 00354 { 00355 m_author = author_; 00356 }
|
|
Set exit value of the process. This value is returned to the shell.
Definition at line 227 of file GenServer.h. References m_exit_value. 00227 { 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 174 of file GenServer.h. References m_log_flag. 00174 { m_log_flag = logf_; }
|
|
Set listening port name.
Definition at line 209 of file GenServer.h. References m_port. 00209 { m_port = port_; }
|
|
Change process name.
Definition at line 185 of file GenServer.h. References m_proc_name. 00185 { m_proc_name = proc_name_; }
|
|
Set Version and Revision number.
Definition at line 345 of file GenServer.h. References m_revision, and m_version. 00346 { 00347 m_version = release_; 00348 m_revision = revision_; 00349 }
|
|
Inform server that it has to stop data processing, clean up and exit. This method will also stop internal Reactor. Definition at line 337 of file GenServer.h. References ASSA::Reactor::deactivate(), m_graceful_quit, and m_reactor. 00338 { 00339 m_graceful_quit = true; 00340 m_reactor.deactivate (); 00341 }
|
|
Temporarily suspend the execution of a service. Corresponds to process leaving RUNNING state and entering SUSPENDED state. Definition at line 110 of file GenServer.h.
|
|
Author's name.
Definition at line 283 of file GenServer.h. Referenced by display_help(), init(), and set_author(). |
|
process name as appeared on command line
Definition at line 234 of file GenServer.h. Referenced by get_cmdline_name(), init(), and init_internals(). |
|
alternative configuration file name
Definition at line 243 of file GenServer.h. Referenced by GenServer(), get_config_file(), and init_internals(). |
|
Daemon option flag. If 'yes', become a UNIX daemon process.
Definition at line 295 of file GenServer.h. Referenced by GenServer(), and init(). |
|
standard configuration file name
Definition at line 240 of file GenServer.h. Referenced by get_default_config_file(), and init_internals(). |
|
Exit value of the process.
Definition at line 323 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 265 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 315 of file GenServer.h. Referenced by GenServer(), and init(). |
|
Help information.
Definition at line 286 of file GenServer.h. Referenced by display_help(), and init(). |
|
Process instance.
Definition at line 249 of file GenServer.h. Referenced by GenServer(), and init(). |
|
Full pathname of debug file.
Definition at line 252 of file GenServer.h. Referenced by GenServer(), and init_internals(). |
|
Log file initialization flag. If RM_LOG, remove old log file.
Definition at line 289 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 304 of file GenServer.h. Referenced by GenServer(). |
|
Log server, assa-logd, address (port@host).
Definition at line 259 of file GenServer.h. Referenced by GenServer(), and init_internals(). |
|
Max size of the log file.
Definition at line 246 of file GenServer.h. Referenced by GenServer(), and init_internals(). |
|
If 'yes', redirects all logging messages to std::cerr.
Definition at line 292 of file GenServer.h. Referenced by GenServer(), and init_internals(). |
|
Debug file mask to filter debug/error messages.
Definition at line 262 of file GenServer.h. Referenced by GenServer(), and init_internals(). |
|
If 'yes', skip PID file locking creation/locking step.
Definition at line 298 of file GenServer.h. Referenced by GenServer(), and init_internals(). |
|
PID File lock path name.
Definition at line 310 of file GenServer.h. Referenced by GenServer(), and init_internals(). |
|
PID File lock.
Definition at line 307 of file GenServer.h. Referenced by init_internals(). |
|
listening port name
Definition at line 237 of file GenServer.h. Referenced by GenServer(), get_port(), and set_port(). |
|
process name (considering instance_number)
Definition at line 231 of file GenServer.h. Referenced by get_proc_name(), init(), init_internals(), and set_proc_name(). |
|
GenServer object has its very own personal Reactor object.
Definition at line 274 of file GenServer.h. Referenced by get_reactor(), and stop_service(). |
|
Software revision (patch) level.
Definition at line 280 of file GenServer.h. Referenced by get_version(), and set_version(). |
|
Signal handlers dispatcher.
Definition at line 268 of file GenServer.h. Referenced by get_sig_manager(). |
|
Function that swallows SIGPOLL calls.
Definition at line 271 of file GenServer.h. |
|
Software version.
Definition at line 277 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 320 of file GenServer.h. Referenced by GenServer(), and init(). |
|
If 'yes', send log messages to the log server.
Definition at line 255 of file GenServer.h. Referenced by GenServer(), and init_internals(). |