Lumiera  0.pre.03
»edit your freedom«
appstate.cpp
Go to the documentation of this file.
1 /*
2  AppState - application initialisation and behaviour
3 
4  Copyright (C) Lumiera.org
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
35 #include "lib/error.hpp"
36 #include "common/appstate.hpp"
38 
39 extern "C" {
41 
42 #include "common/interface.h"
44 #include "common/plugin.h"
45 }
46 
47 #include "lib/symbol.hpp"
48 #include "lib/util.hpp"
49 
50 
51 using lib::Literal;
52 using std::unique_ptr;
53 
54 
55 
56 namespace lumiera {
57 
58  namespace { // implementation details
59 
60  inline void
61  log_and_clear_unexpected_errorstate ()
62  {
63  if (lumiera_err errorstate = lumiera_error ())
64  ALERT (common, "*** Unexpected error: %s\n Triggering emergency exit.", errorstate);
65  }
66  }
67 
68 
69 
70 
82  , subsystems_{}
83  , emergency_{false}
84  , core_up_{false}
85  { }
86 
89 
90 
91  string
93  {
94  return setup_.get(key).as<string>();
95  }
96 
97 
98 
99 
100 
101  // ===== Implementation startup and shutdown sequence for main() ========
102 
103 
104 #define _MAYBE_THROW_ \
105  maybeThrow<error::Fatal> ("internal failure while initialising the "\
106  "Lumiera application framework");
107 
108 
109 
110  void
112  {
113  TRACE (common, "initialising application core...");
114 
116  _MAYBE_THROW_
117 
119  _MAYBE_THROW_
120 
121  lumiera_config_interface_init ();
122  _MAYBE_THROW_
123 
124  core_up_= true;
126  _MAYBE_THROW_
127 
128 
129  subsystems_.reset (new SubsystemRunner (options));
130  TRACE (common, "Lumiera core started successfully.");
131  }
132 
133 
134 
135  void
137  {
138  TRACE (common, "maybe startup %s...?", cStr(subsys));
139  REQUIRE (subsystems_);
140  subsystems_->maybeRun (subsys);
141  }
142 
143 
144 
145  typedef AppState::ExitCode ExitCode;
146 
147 
160  ExitCode
162  {
163  if (subsystems_)
164  {
165  emergency_ |= subsystems_->wait();
166  subsystems_.reset(0);
167  }
168 
169  NOTICE (common, "Shutting down Lumiera...");
170 
171  if (emergency_)
172  {
173  ALERT (common, "Triggering emergency exit...");
175  return CLEAN_EMERGENCY_EXIT;
176  }
177  else
178  {
180  return NORMAL_EXIT;
181  }
182  }
183 
184 
185 
186  ExitCode
188  {
189 
190  ERROR (common, "Aborting Lumiera after unhandled error: %s", cStr(problem.what()));
191 
192  log_and_clear_unexpected_errorstate();
193 
194  try
195  {
196  if (subsystems_)
197  {
198  subsystems_->triggerEmergency(true);
199  subsystems_->shutdownAll();
200  }
201  return maybeWait ();
202  }
203  catch (...)
204  {
205  return abort();
206  }
207  }
208 
209 
210 
211  ExitCode
212  AppState::abort () noexcept
213  {
214  log_and_clear_unexpected_errorstate();
215 
216  if (emergency_)
217  {
219  return FAILED_EMERGENCY_EXIT;
220  }
221  else
222  {
224  return CLEAN_EXIT_AFTER_ERROR;
225  }
226  }
227 
228 
229 
230 
237  {
238  if (core_up_)
239  try
240  {
241  TRACE (common, "shutting down basic application layer...");
242  lumiera_config_interface_destroy ();
243  lumiera_interfaceregistry_destroy ();
244  }
245  catch (...)
246  {
247  log_and_clear_unexpected_errorstate();
248  } }
249 
250 
251 
252 
253 } // namespace lumiera
ExitCode abort() noexcept
initiate an fatal emergency shutdown, caused by an unforeseen error condition
Definition: appstate.cpp:212
Dependencies and lifecycle of a partially independent Subsystem of the Application.
Definition: subsys.hpp:70
AppState()
perform initialisation triggered on first access.
Definition: appstate.cpp:80
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
Definition: symbol.hpp:68
int lumiera_plugin_register(LumieraPlugin plugin)
Register a plugin and its interfaces.
Definition: plugin.c:269
LumieraPlugin lumiera_plugin_load(const char *plugin)
Tries to load a plugin Creates a new plugin structure and tries to load and initialise the plugin...
Definition: plugin.c:250
~AppState()
anything which should be closed as late as possible and after the normal shutdown sequence can be pla...
Definition: appstate.cpp:236
const char * ON_GLOBAL_SHUTDOWN
to be triggered at the end of main()
Lumiera plugins define &#39;interfaces&#39; as shown in interface.h, the plugin system handles the loading of...
#define LUMIERA_LOCATION_OF_BOOTSTRAP_INI
"bootstrapIni" : the basic setup configuration to load
Definition: basic-setup.hpp:66
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:85
virtual CStr what() const noexcept override
std::exception interface : yield a diagnostic message
Frontend for handling the Lumiera application commandline arguments.
Definition: option.hpp:77
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:289
static void trigger(Symbol eventLabel)
trigger lifecycle callbacks registered under the given label
Definition: lifecycle.cpp:81
void maybeStart(lumiera::Subsys &)
building on the state determined by init, decide if the given Subsys needs to be pulled up and...
Definition: appstate.cpp:136
Lumiera interface macros and structures.
Marker types to indicate a literal string and a Symbol.
Implementation helper for managing execution of a collection of subsystems, which may depend on one a...
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
int lumiera_plugin_discover(LumieraPlugin(*callback_load)(const char *plugin), int(*callback_register)(LumieraPlugin))
discover new plugins traverses the configured plugin paths and calls the callback_load function for a...
Definition: plugin.c:196
lumiera_err lumiera_error(void)
Get and clear current error state.
Definition: error-state.c:124
const char * ON_GLOBAL_INIT
to be triggered in main()
void init(lumiera::Option &options)
evaluate the result of option parsing and maybe additional configuration such as to be able to determ...
Definition: appstate.cpp:111
void lumiera_interfaceregistry_init(void)
Initialise the interface registry.
Lumiera error handling (C++ interface).
Global registry for interfaces (extension points).
ExitCode maybeWait()
put the main thread of the application into a wait state, as long as some subsystem(s) registered wit...
Definition: appstate.cpp:161
string fetchSetupValue(lib::Literal key)
access basic application setup values (from setup.ini)
Definition: appstate.cpp:92
Registering and managing primary application-global services.
Manage execution of the independent Subsystems of the Lumiera application.
External interface to the lumiera configuration system.
Lumiera public interface.
Definition: advice.cpp:113
static lib::Depend< AppState > instance
get the (single) AppState instance.
Definition: appstate.hpp:83
const char * ON_EMERGENCY
activated on shutdown after premature failure of a subsystem
Interface and Base definition for all Lumiera Exceptions.
Definition: error.hpp:71