PageRenderTime 57ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/llapp.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 345 lines | 127 code | 55 blank | 163 comment | 0 complexity | ec71e507be7188c3b3bc62e938a56a54 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llapp.h
  3. * @brief Declaration of the LLApp class.
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLAPP_H
  27. #define LL_LLAPP_H
  28. #include <map>
  29. #include "llrun.h"
  30. #include "llsd.h"
  31. #include "lloptioninterface.h"
  32. // Forward declarations
  33. template <typename Type> class LLAtomic32;
  34. typedef LLAtomic32<U32> LLAtomicU32;
  35. class LLErrorThread;
  36. class LLLiveFile;
  37. #if LL_LINUX
  38. typedef struct siginfo siginfo_t;
  39. #endif
  40. typedef void (*LLAppErrorHandler)();
  41. typedef void (*LLAppChildCallback)(int pid, bool exited, int status);
  42. #if !LL_WINDOWS
  43. extern S32 LL_SMACKDOWN_SIGNAL;
  44. extern S32 LL_HEARTBEAT_SIGNAL;
  45. // Clear all of the signal handlers (which we want to do for the child process when we fork
  46. void clear_signals();
  47. class LLChildInfo
  48. {
  49. public:
  50. LLChildInfo() : mGotSigChild(FALSE), mCallback(NULL) {}
  51. BOOL mGotSigChild;
  52. LLAppChildCallback mCallback;
  53. };
  54. #endif
  55. namespace google_breakpad {
  56. class ExceptionHandler; // See exception_handler.h
  57. }
  58. class LL_COMMON_API LLApp : public LLOptionInterface
  59. {
  60. friend class LLErrorThread;
  61. public:
  62. typedef enum e_app_status
  63. {
  64. APP_STATUS_RUNNING, // The application is currently running - the default status
  65. APP_STATUS_QUITTING, // The application is currently quitting - threads should listen for this and clean up
  66. APP_STATUS_STOPPED, // The application is no longer running - tells the error thread it can exit
  67. APP_STATUS_ERROR // The application had a fatal error occur - tells the error thread to run
  68. } EAppStatus;
  69. LLApp();
  70. virtual ~LLApp();
  71. protected:
  72. LLApp(LLErrorThread* error_thread);
  73. void commonCtor();
  74. public:
  75. /**
  76. * @brief Return the static app instance if one was created.
  77. */
  78. static LLApp* instance();
  79. /** @name Runtime options */
  80. //@{
  81. /**
  82. * @brief Enumeration to specify option priorities in highest to
  83. * lowest order.
  84. */
  85. enum OptionPriority
  86. {
  87. PRIORITY_RUNTIME_OVERRIDE,
  88. PRIORITY_COMMAND_LINE,
  89. PRIORITY_SPECIFIC_CONFIGURATION,
  90. PRIORITY_GENERAL_CONFIGURATION,
  91. PRIORITY_DEFAULT,
  92. PRIORITY_COUNT
  93. };
  94. /**
  95. * @brief Get the application option at the highest priority.
  96. *
  97. * If the return value is undefined, the option does not exist.
  98. * @param name The name of the option.
  99. * @return Returns the option data.
  100. */
  101. virtual LLSD getOption(const std::string& name) const;
  102. /**
  103. * @brief Parse command line options and insert them into
  104. * application command line options.
  105. *
  106. * The name inserted into the option will have leading option
  107. * identifiers (a minus or double minus) stripped. All options
  108. * with values will be stored as a string, while all options
  109. * without values will be stored as true.
  110. * @param argc The argc passed into main().
  111. * @param argv The argv passed into main().
  112. * @return Returns true if the parse succeeded.
  113. */
  114. bool parseCommandOptions(int argc, char** argv);
  115. /**
  116. * @brief Keep track of live files automatically.
  117. *
  118. * *TODO: it currently uses the <code>addToEventTimer()</code> API
  119. * instead of the runner. I should probalby use the runner.
  120. *
  121. * *NOTE: DO NOT add the livefile instance to any kind of check loop.
  122. *
  123. * @param livefile A valid instance of an LLLiveFile. This LLApp
  124. * instance will delete the livefile instance.
  125. */
  126. void manageLiveFile(LLLiveFile* livefile);
  127. /**
  128. * @brief Set the options at the specified priority.
  129. *
  130. * This function completely replaces the options at the priority
  131. * level with the data specified. This function will make sure
  132. * level and data might be valid before doing the replace.
  133. * @param level The priority level of the data.
  134. * @param data The data to set.
  135. * @return Returns true if the option was set.
  136. */
  137. bool setOptionData(OptionPriority level, LLSD data);
  138. /**
  139. * @brief Get the option data at the specified priority.
  140. *
  141. * This method is probably not so useful except when merging
  142. * information.
  143. * @param level The priority level of the data.
  144. * @return Returns The data (if any) at the level priority.
  145. */
  146. LLSD getOptionData(OptionPriority level);
  147. //@}
  148. //
  149. // Main application logic
  150. //
  151. virtual bool init() = 0; // Override to do application initialization
  152. //
  153. // cleanup()
  154. //
  155. // It's currently assumed that the cleanup() method will only get
  156. // called from the main thread or the error handling thread, as it will
  157. // likely do thread shutdown, among other things.
  158. //
  159. virtual bool cleanup() = 0; // Override to do application cleanup
  160. //
  161. // mainLoop()
  162. //
  163. // Runs the application main loop. It's assumed that when you exit
  164. // this method, the application is in one of the cleanup states, either QUITTING or ERROR
  165. //
  166. virtual bool mainLoop() = 0; // Override for the application main loop. Needs to at least gracefully notice the QUITTING state and exit.
  167. //
  168. // Crash logging
  169. //
  170. void disableCrashlogger(); // Let the OS handle the crashes
  171. static bool isCrashloggerDisabled(); // Get the here above set value
  172. //
  173. // Application status
  174. //
  175. static void setQuitting(); // Set status to QUITTING, the app is now shutting down
  176. static void setStopped(); // Set status to STOPPED, the app is done running and should exit
  177. static void setError(); // Set status to ERROR, the error handler should run
  178. static bool isStopped();
  179. static bool isRunning();
  180. static bool isQuitting();
  181. static bool isError();
  182. static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
  183. #if !LL_WINDOWS
  184. static U32 getSigChildCount();
  185. static void incSigChildCount();
  186. #endif
  187. static int getPid();
  188. /** @name Error handling methods */
  189. //@{
  190. /**
  191. * @brief Do our generic platform-specific error-handling setup --
  192. * signals on unix, structured exceptions on windows.
  193. *
  194. * DO call this method if your app will either spawn children or be
  195. * spawned by a launcher.
  196. * Call just after app object construction.
  197. * (Otherwise your app will crash when getting signals,
  198. * and will not core dump.)
  199. *
  200. * DO NOT call this method if your application has specialized
  201. * error handling code.
  202. */
  203. void setupErrorHandling();
  204. void setErrorHandler(LLAppErrorHandler handler);
  205. static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
  206. //@}
  207. // the maximum length of the minidump filename returned by getMiniDumpFilename()
  208. static const U32 MAX_MINDUMP_PATH_LENGTH = 256;
  209. // change the directory where Breakpad minidump files are written to
  210. void setMiniDumpDir(const std::string &path);
  211. // Return the Google Breakpad minidump filename after a crash.
  212. char *getMiniDumpFilename() { return minidump_path; }
  213. // Write out a Google Breakpad minidump file.
  214. void writeMiniDump();
  215. #if !LL_WINDOWS
  216. //
  217. // Child process handling (Unix only for now)
  218. //
  219. // Set a callback to be run on exit of a child process
  220. // WARNING! This callback is run from the signal handler due to
  221. // Linux threading requiring waitpid() to be called from the thread that spawned the process.
  222. // At some point I will make this more behaved, but I'm not going to fix this right now - djs
  223. void setChildCallback(pid_t pid, LLAppChildCallback callback);
  224. // The child callback to run if no specific handler is set
  225. void setDefaultChildCallback(LLAppChildCallback callback);
  226. // Fork and do the proper signal handling/error handling mojo
  227. // *NOTE: You need to make sure your signal handling callback is
  228. // correct after you fork, because not all threads are duplicated
  229. // when you fork!
  230. pid_t fork();
  231. #endif
  232. /**
  233. * @brief Get a reference to the application runner
  234. *
  235. * Please use the runner with caution. Since the Runner usage
  236. * pattern is not yet clear, this method just gives access to it
  237. * to add and remove runnables.
  238. * @return Returns the application runner. Do not save the
  239. * pointer past the caller's stack frame.
  240. */
  241. LLRunner& getRunner() { return mRunner; }
  242. public:
  243. typedef std::map<std::string, std::string> string_map;
  244. string_map mOptionMap; // Contains all command-line options and arguments in a map
  245. protected:
  246. static void setStatus(EAppStatus status); // Use this to change the application status.
  247. static EAppStatus sStatus; // Reflects current application status
  248. static BOOL sErrorThreadRunning; // Set while the error thread is running
  249. static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
  250. #if !LL_WINDOWS
  251. static LLAtomicU32* sSigChildCount; // Number of SIGCHLDs received.
  252. typedef std::map<pid_t, LLChildInfo> child_map; // Map key is a PID
  253. static child_map sChildMap;
  254. static LLAppChildCallback sDefaultChildCallback;
  255. #endif
  256. /**
  257. * @brief This method is called once a frame to do once a frame tasks.
  258. */
  259. void stepFrame();
  260. private:
  261. void startErrorThread();
  262. // Contains the filename of the minidump file after a crash.
  263. char minidump_path[MAX_MINDUMP_PATH_LENGTH];
  264. // *NOTE: On Windows, we need a routine to reset the structured
  265. // exception handler when some evil driver has taken it over for
  266. // their own purposes
  267. typedef int(*signal_handler_func)(int signum);
  268. static LLAppErrorHandler sErrorHandler;
  269. // Default application threads
  270. LLErrorThread* mThreadErrorp; // Waits for app to go to status ERROR, then runs the error callback
  271. // This is the application level runnable scheduler.
  272. LLRunner mRunner;
  273. /** @name Runtime option implementation */
  274. //@{
  275. // The application options.
  276. LLSD mOptions;
  277. // The live files for this application
  278. std::vector<LLLiveFile*> mLiveFiles;
  279. //@}
  280. private:
  281. // the static application instance if it was created.
  282. static LLApp* sApplication;
  283. google_breakpad::ExceptionHandler * mExceptionHandler;
  284. #if !LL_WINDOWS
  285. friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);
  286. #endif
  287. public:
  288. static BOOL sLogInSignal;
  289. };
  290. #endif // LL_LLAPP_H