/* ---- This file is part of SECONDO. Copyright (C) 2004-2007, University in Hagen, Faculty for Mathematics and Computer Science, Database Systems for New Applications. SECONDO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. SECONDO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- //paragraph [10] title: [{\Large \bf ] [}] //paragraph [11] title: [{\large \bf ] [}] //paragraph [12] title: [{\normalsize \bf ] [}] //paragraph [21] table1column: [\begin{quote}\begin{tabular}{l}] [\end{tabular}\end{quote}] //paragraph [22] table2columns: [\begin{quote}\begin{tabular}{ll}] [\end{tabular}\end{quote}] //paragraph [23] table3columns: [\begin{quote}\begin{tabular}{lll}] [\end{tabular}\end{quote}] //paragraph [24] table4columns: [\begin{quote}\begin{tabular}{llll}] [\end{tabular}\end{quote}] //[--------] [\hline] //characters [1] verbatim: [$] [$] //characters [2] formula: [$] [$] //characters [4] teletype: [\texttt{] [}] //[ae] [\"a] //[oe] [\"o] //[ue] [\"u] //[ss] [{\ss}] //[<=] [\leq] //[#] [\neq] //[tilde] [\verb|~|] 1 Header File: Application Management April 2002 Ulrich Telle 1.1 Overview The module ~Application~ provides support for managing an application process. Access to the name of the executable and the command line parameters is offered in a portable way. When used together with the module ~Processes~ a very simple process communication based on a signal mechanism is available. Currently two user defined signals and a termination signal are supported. The user signals are flagged in member variables of the application and can be queried and reset at any time. For handling a termination signal two different ways are offered: First, simple flagging is possible and the flag can be queried at any time in the event loop of the application. The flag should be checked regularly and appropriate action should be taken when it is set. Second, the application could provide overwrite the empty virtual method ~AbortOnSignal~. In this method any application specific clean up could take place. If the method returns to the calling signal handler the application is exited with a return code of *-999*. Additionally a communication socket can be passed from a parent process to its child processes in an operating system independent manner. Usually the application developer derives his own class from the ~Application~ base class. Only one instance of an application is allowed. The instantiation of the application should be the very first task in the main program, since the signal mechanism is activated in the constructor and could miss signals when not created immediately after start up of the application. 1.2 Interface Methods This module offers the following routines: [23] Creation/Removal & Information retrieval & Process Communication \\ [--------] Application & GetArgCount & GetParent \\ [tilde]Application & GetArgValues & HasSocket \\ & GetApplicationName & GetSocket \\ & GetApplicationPath & ShouldAbort \\ & Instance & GetUser1Flag \\ & GetOwnProcessId & GetUser2Flag \\ & & ResetUser1Flag \\ & Sleep & ResetUser2Flag \\ 1.3 Imports, Constants, Types */ #ifndef APPLICATION_H #define APPLICATION_H #include #include #include #include #include "SecondoConfig.h" #include "SocketIO.h" #include "LogMsg.h" #include "FileSystem.h" #ifndef SECONDO_PID #define SECONDO_PID #ifndef SECONDO_WIN32 typedef int ProcessId; #define INVALID_PID (-1) #else #include typedef DWORD ProcessId; #define INVALID_PID ((DWORD)-1) #endif #endif extern CMsg cmsg; /* 1.4 Class "Application"[1] This class provides an application framework. */ class SDB_EXPORT Application { public: Application( int argc, const char **argv ); /* Creates and initializes the ~Application~ object. *NOTE*: The constructor is usually called directly from the program's main() routine. The parameters ~argc~ and ~argv~ are usually those passed to the main() function. *NOTE*: Only exactly *one* ~Application~ instance is allowed per process. */ virtual ~Application(); /* Destroys the ~Application~ object. */ int GetArgCount() const { return (argCount); }; /* Returns the number of command line arguments. */ const char** GetArgValues() const { return (argValues); }; /* Returns the pointer to the array of command line arguments. */ const std::string GetApplicationName() const { return (appName); }; /* Returns the name of the executable file. */ const std::string GetApplicationPath() const { return (appPath); }; /* Returns the path name where the application was started from. */ ProcessId GetOwnProcessId() { return (ownpid); }; /* Returns the real process identification of the process itself. */ ProcessId GetParent() { return (parent); }; /* Returns the real process identification of the parent process, if available. If it is not available "INVALID\_PID"[4] is returned. *NOTE*: Unfortunately this information is not available on all platforms. For example the operating system ~Microsoft Windows~ does not provide it on its own, but for child processes which are created using the ~ProcessFactory~ class the parent process identification is accessible. */ static Application* Instance(); /* Returns a reference to the single ~Application~ instance. */ bool ShouldAbort() const { return (abortFlag); }; /* Checks whether the abort flag was set by a signal handler. If this method returns "true"[4], the application should terminate as soon as possible. */ bool GetUser1Flag() { return (user1Flag); }; bool GetUser2Flag() { return (user2Flag); }; /* Check whether one of the user flags has been set by a remote signal. */ void ResetUser1Flag() { user1Flag = false; }; void ResetUser2Flag() { user2Flag = false; }; /* Reset the user flags to unsignaled state, thus allowing to receive further user signals. The meaning of these signals is not defined by the ~Application~ class. */ bool HasSocket() { return (hasSocket); }; /* Returns "true"[4] if a socket handle was passed to the application through the argument list. *NOTE*: This is useful for communication server processes where a listener process starts a child process for servicing client requests. */ Socket* GetSocket() { return (clientSocket); }; /* Returns a reference to the socket, which might be passed to the application through the argument list. */ static void Sleep( const int seconds ); /* Causes the application to enter a wait state until a time interval of ~seconds~ seconds has expired. */ /* The following methodes are only available to derived application classes: */ protected: void SetAbortMode( bool activate ) { abortMode = activate; }; /* Activates or deactivates the abortion mode of the application. When the abortion mode is *activated*, the method ~AbortOnSignal~ is invoked, when the application receives a signal on which the application should be terminated. After return from the method ~AbortOnSignal~ the application is terminated immediately. When the abortion mode is *not activated*, the method ~AbortOnSignal~ is *not* invoked, when the application receives a signal on which the application should be terminated. Instead an abort flag is set which should be checked regularly in the event loop of the application. */ bool GetAbortMode() { return (abortMode); }; /* Returns the current state of the abort mode. If the abort mode is activated "true"[4] is returned, otherwise "false"[4]. */ virtual bool AbortOnSignal ( int __attribute__((unused)) sig )const { return (true); }; /* Is called by the application's default signal handler whenever a signal is caught that would have aborted the process anyway. This is the case for most signals like "SIGTERM"[4], "SIGQUIT"[4] and so on. The pre-installed signal handler ensures proper application shutdown in such circumstances. */ private: int argCount; // number of arguments const char** argValues; // array of arguments std::string appName; // name of application std::string appPath; // path of application ProcessId ownpid; // own process id ProcessId parent; // parent process id bool hasSocket; // flag Socket* clientSocket; // reference to client socket int lastSignal; // last signal received bool abortMode; // abort mode volatile bool abortFlag; // abort signal flag volatile bool user1Flag; // user1 signal flag volatile bool user2Flag; // user2 signal flag #ifndef SECONDO_WIN32 static void AbortOnSignalHandler( int sig ); /* Is the default signal handler for handling signals which usually would terminate the process. */ static void UserSignalHandler( int sig ); /* Is the default signal handler for handling user signals (SIGUSR1 and SIGUSR2). */ #else Socket* rshSocket; DWORD WINAPI RemoteSignalHandler(); static DWORD WINAPI RemoteSignalThread( LPVOID app ) { return (((Application*) app)->RemoteSignalHandler()); } static BOOL __stdcall AbortOnSignalHandler( DWORD sig ); /* These methods emulate the signal mechanism for the ~Microsoft Windows~ platform. */ #endif static Application* appPointer; static std::map signalStr; static bool dumpStacktrace; // Dump stacktrace on app crash static char* stacktraceOutput; // Output filename for stacktraces static char* relocationInfo; // Relocation info (for -fPIC binaries) }; #endif // APPLICATION_H