llapp.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LLAPP_H
00033 #define LL_LLAPP_H
00034 
00035 #include <map>
00036 #include "llapr.h"
00037 #include "llrun.h"
00038 #include "llsd.h"
00039 
00040 // Forward declarations
00041 class LLErrorThread;
00042 class LLApp;
00043 
00044 
00045 typedef void (*LLAppErrorHandler)();
00046 typedef void (*LLAppChildCallback)(int pid, bool exited, int status);
00047 
00048 #if !LL_WINDOWS
00049 extern const S32 LL_SMACKDOWN_SIGNAL;
00050 
00051 // Clear all of the signal handlers (which we want to do for the child process when we fork
00052 void clear_signals();
00053 
00054 class LLChildInfo
00055 {
00056 public:
00057         LLChildInfo() : mGotSigChild(FALSE), mCallback(NULL) {}
00058         BOOL mGotSigChild;
00059         LLAppChildCallback mCallback;
00060 };
00061 #endif
00062 
00063 class LLApp
00064 {
00065         friend class LLErrorThread;
00066 public:
00067         typedef enum e_app_status
00068         {
00069                 APP_STATUS_RUNNING,             // The application is currently running - the default status
00070                 APP_STATUS_QUITTING,    // The application is currently quitting - threads should listen for this and clean up
00071                 APP_STATUS_STOPPED,             // The application is no longer running - tells the error thread it can exit
00072                 APP_STATUS_ERROR                // The application had a fatal error occur - tells the error thread to run
00073         } EAppStatus;
00074 
00075 
00076         LLApp();
00077         virtual ~LLApp();
00078 
00082         static LLApp* instance();
00083 
00090         enum OptionPriority
00091         {
00092                 PRIORITY_RUNTIME_OVERRIDE,
00093                 PRIORITY_COMMAND_LINE,
00094                 PRIORITY_SPECIFIC_CONFIGURATION,
00095                 PRIORITY_GENERAL_CONFIGURATION,
00096                 PRIORITY_DEFAULT,
00097                 PRIORITY_COUNT
00098         };
00099 
00107         LLSD getOption(const std::string& name) const;
00108 
00121         bool parseCommandOptions(int argc, char** argv);
00122 
00133         bool setOptionData(OptionPriority level, LLSD data);
00134 
00143         LLSD getOptionData(OptionPriority level);
00145 
00146 
00147 
00148         //
00149         // Main application logic
00150         //
00151         virtual bool init() = 0;                        // Override to do application initialization
00152 
00153         //
00154         // cleanup()
00155         //
00156         // It's currently assumed that the cleanup() method will only get
00157         // called from the main thread or the error handling thread, as it will
00158         // likely do thread shutdown, among other things.
00159         //
00160         virtual bool cleanup() = 0;                     // Override to do application cleanup
00161 
00162         //
00163         // mainLoop()
00164         //
00165         // Runs the application main loop.  It's assumed that when you exit
00166         // this method, the application is in one of the cleanup states, either QUITTING or ERROR
00167         //
00168         virtual bool mainLoop() = 0; // Override for the application main loop.  Needs to at least gracefully notice the QUITTING state and exit.
00169 
00170 
00171         //
00172         // Application status
00173         //
00174         static void setQuitting();      // Set status to QUITTING, the app is now shutting down
00175         static void setStopped();       // Set status to STOPPED, the app is done running and should exit
00176         static void setError();         // Set status to ERROR, the error handler should run
00177         static bool isStopped();
00178         static bool isRunning();
00179         static bool isQuitting();
00180         static bool isError();
00181         static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
00182 #if !LL_WINDOWS
00183         static U32  getSigChildCount();
00184         static void incSigChildCount();
00185 #endif
00186         static int getPid();
00187 
00188         //
00189         // Error handling methods
00190         //
00191         void setErrorHandler(LLAppErrorHandler handler);
00192 
00193 #if !LL_WINDOWS
00194         //
00195         // Child process handling (Unix only for now)
00196         //
00197         // Set a callback to be run on exit of a child process
00198         // WARNING!  This callback is run from the signal handler due to the extreme crappiness of
00199         // Linux threading requiring waitpid() to be called from the thread that spawned the process.
00200         // At some point I will make this more behaved, but I'm not going to fix this right now - djs
00201         void setChildCallback(pid_t pid, LLAppChildCallback callback);
00202 
00203     // The child callback to run if no specific handler is set
00204         void setDefaultChildCallback(LLAppChildCallback callback); 
00205         
00206     // Fork and do the proper signal handling/error handling mojo
00207         // WARNING: You need to make sure your signal handling callback is correct after
00208         // you fork, because not all threads are duplicated when you fork!
00209         pid_t fork(); 
00210 #endif
00211 
00221         LLRunner& getRunner() { return mRunner; }
00222 
00223 public:
00224         typedef std::map<std::string, std::string> string_map;
00225         string_map mOptionMap;  // Contains all command-line options and arguments in a map
00226 
00227 protected:
00228 
00229         static void setStatus(EAppStatus status);               // Use this to change the application status.
00230         static EAppStatus sStatus; // Reflects current application status
00231         static BOOL sErrorThreadRunning; // Set while the error thread is running
00232 
00233 #if !LL_WINDOWS
00234         static LLAtomicU32* sSigChildCount; // Number of SIGCHLDs received.
00235         typedef std::map<pid_t, LLChildInfo> child_map; // Map key is a PID
00236         static child_map sChildMap;
00237         static LLAppChildCallback sDefaultChildCallback;
00238 #endif
00239 
00243         void stepFrame();
00244 
00245 private:
00246         void setupErrorHandling();              // Do platform-specific error-handling setup (signals, structured exceptions)
00247 
00248         static void runErrorHandler();
00249 
00250         // *NOTE: On Windows, we need a routine to reset the structured
00251         // exception handler when some evil driver has taken it over for
00252         // their own purposes
00253         typedef int(*signal_handler_func)(int signum);
00254         static LLAppErrorHandler sErrorHandler;
00255 
00256         // Default application threads
00257         LLErrorThread* mThreadErrorp;           // Waits for app to go to status ERROR, then runs the error callback
00258 
00259         // This is the application level runnable scheduler.
00260         LLRunner mRunner;
00261 
00264 
00265         // The application options.
00266         LLSD mOptions;
00267 
00269 
00270 private:
00271         // the static application instance if it was created.
00272         static LLApp* sApplication;
00273 
00274 
00275 #if !LL_WINDOWS
00276         friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);
00277 #endif
00278 
00279 public:
00280         static BOOL sLogInSignal;
00281 };
00282 
00283 #endif // LL_LLAPP_H

Generated on Thu Jul 1 06:08:19 2010 for Second Life Viewer by  doxygen 1.4.7