00001 #ifndef STARTUP_CODE_IMPLEMENTATION_FILE
00002 #define STARTUP_CODE_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "critical_events.h"
00019 #include "path_configuration.h"
00020 #include "startup_code.h"
00021 #ifndef OMIT_PROGRAM_WIDE_LOGGER
00022 #include "console_logger.h"
00023 #include "file_logger.h"
00024 #include "locked_logger.h"
00025 #include "null_logger.h"
00026 #endif
00027 #include "system_values.h"
00028
00029 #include <basis/byte_array.h>
00030 #include <basis/chaos.h>
00031 #include <basis/guards.h>
00032 #include <basis/istring.h>
00033 #include <basis/memory_checker.h>
00034 #include <data_struct/static_memory_gremlin.h>
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <memory.h>
00039
00040
00041
00042
00043 #ifdef DEBUG_STARTUP_CODE
00044 #include <stdio.h>
00045 #endif
00046
00047 #define static_class_name() "startup_code"
00048
00050
00051 namespace startup_code {
00052 const char *_EXCEPTION_INFO_FOR_SHUTTING_DOWN
00053 = "Function must return immediately because program is shutting down.";
00054 static bool _program_is_dying = false;
00055
00056
00057
00058 bool BASIS_EXTERN program_is_dying() { return _program_is_dying; }
00059
00060 const char BASIS_EXTERN *EXCEPTION_INFO_FOR_SHUTTING_DOWN()
00061 { return _EXCEPTION_INFO_FOR_SHUTTING_DOWN; }
00062 }
00063
00065
00066 #ifdef ENABLE_MEMORY_HOOK
00067
00068 static memory_checker *__exposed_hidden_memories = NIL;
00069
00070
00071
00072 void hoople_atexit()
00073 {
00074 if (__exposed_hidden_memories) {
00075 __exposed_hidden_memories->destruct();
00076
00077 __exposed_hidden_memories = NIL;
00078 }
00079 }
00080
00082
00084
00090 memory_checker BASIS_EXTERN &program_wide_memories()
00091 {
00092 static memory_checker *_hidden_memories = NIL;
00093 if (!_hidden_memories) {
00094 static bool _already_here = false;
00095 if (_already_here) {
00096 printf("logic error in program_wide_memories: invoked after shutdown\n");
00097 abort();
00098 }
00099 _already_here = true;
00100
00101 _hidden_memories = (memory_checker *)malloc(sizeof(memory_checker));
00102 _hidden_memories->construct();
00103
00104 __exposed_hidden_memories = _hidden_memories;
00105
00106 atexit(hoople_atexit);
00107 }
00108 return *_hidden_memories;
00109
00110
00111
00112 }
00113
00114 #endif
00115
00117
00118 #ifdef ENABLE_CALLSTACK_TRACKING
00119
00121
00128 callstack_tracker BASIS_EXTERN &program_wide_stack_trace()
00129 {
00130 static callstack_tracker *_hidden_trace = NIL;
00131 if (!_hidden_trace) {
00132 #ifdef ENABLE_MEMORY_HOOK
00133 program_wide_memories().disable();
00134
00135
00136 #endif
00137 _hidden_trace = new callstack_tracker;
00138 #ifdef ENABLE_MEMORY_HOOK
00139 program_wide_memories().enable();
00140 #endif
00141 }
00142 return *_hidden_trace;
00143 }
00144
00145 #endif
00146
00148
00149 locked_logger OPSYSTEM_FUNCTION_STYLE &real_program_wide_logger()
00150 {
00151 SAFE_STATIC_IMPLEMENTATION(locked_logger, , __LINE__);
00152 }
00153
00154 #ifndef OMIT_PROGRAM_WIDE_LOGGER
00155
00156 log_base OPSYSTEM_FUNCTION_STYLE &program_wide_logger()
00157 {
00158 if (!real_program_wide_logger().established()) {
00159 SET_DEFAULT_NULL_LOGGER;
00160 critical_events::write_to_critical_events((timestamp(true, true)
00161 + "the program-wide logger isn't set!").s());
00162 }
00163 return real_program_wide_logger();
00164 }
00165
00166 log_base OPSYSTEM_FUNCTION_STYLE *retask_program_wide_logger
00167 (log_base *new_logger)
00168 {
00169 return real_program_wide_logger().swap(new_logger);
00170 }
00171 #endif
00172
00174
00175 namespace startup_code {
00176
00177
00178
00179
00180
00181
00182
00183 static_memory_gremlin &HOOPLE_GLOBALS()
00184 {
00185 static bool _initted = false;
00186 static static_memory_gremlin *_internal_gremlin = NIL;
00187
00188
00189 if (!_initted) {
00190 #ifdef DEBUG_STARTUP_CODE
00191 printf("%s: initializing HOOPLE_GLOBALS now.\n", __argv[0]);
00192 #endif
00193
00194 #ifdef ENABLE_MEMORY_HOOK
00195 void *temp = program_wide_memories().provide_memory(1, __FILE__, __LINE__);
00196
00197 program_wide_memories().release_memory(temp);
00198 #endif
00199
00200 #ifdef ENABLE_CALLSTACK_TRACKING
00201 program_wide_stack_trace().full_trace_size();
00202
00203 #endif
00204 FUNCDEF("HOOPLE_GLOBALS remainder");
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 _internal_gremlin = new static_memory_gremlin;
00217 _initted = true;
00218 }
00219
00220 return *_internal_gremlin;
00221 }
00222
00224
00225 library_wide_cleanup::library_wide_cleanup()
00226 : _shared_chunks(&HOOPLE_GLOBALS())
00227 {
00228 startup_code::__memory_gremlin_synchronizer();
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 istring::empty_string();
00241 byte_array::empty_array();
00242 }
00243
00244 library_wide_cleanup::~library_wide_cleanup() {}
00245
00246
00248
00249 program_wide_cleanup::program_wide_cleanup()
00250 {
00251
00252
00253 chaos().retrain();
00254 #ifndef OMIT_PROGRAM_WIDE_LOGGER
00255
00256
00257 SET_DEFAULT_COMBO_LOGGER;
00258 #endif
00259 }
00260
00261 program_wide_cleanup::~program_wide_cleanup()
00262 {
00263 #ifndef OMIT_PROGRAM_WIDE_LOGGER
00264 if (real_program_wide_logger().established()) {
00265 SET_DEFAULT_NULL_LOGGER;
00266
00267
00268
00269
00270 }
00271 #endif
00272
00273
00274 static_memory_gremlin *shared = &HOOPLE_GLOBALS();
00275
00276 _program_is_dying = true;
00277
00278
00279 WHACK(shared);
00280 }
00281
00283
00284
00285
00286
00287
00288
00289 mutex &__memory_gremlin_synchronizer()
00290 {
00291 const char *hoople_static_name
00292 = ":" __FILE__ ":" "only___memory_gremlin_synch" ":";
00293 static mutex *_hidden_mutt = dynamic_cast<mutex *>
00294 (HOOPLE_GLOBALS().get(hoople_static_name));
00295 if (!_hidden_mutt) {
00296 _hidden_mutt = new mutex;
00297 HOOPLE_GLOBALS().put(hoople_static_name, _hidden_mutt);
00298 }
00299 return *_hidden_mutt;
00300 }
00301
00302 mutex &__uptime_synchronizer()
00303 { SAFE_STATIC_IMPLEMENTATION(mutex, , __LINE__); }
00304
00305 mutex &__process_synchronizer()
00306 { SAFE_STATIC_IMPLEMENTATION(mutex, , __LINE__); }
00307
00308 }
00309
00311
00312
00313
00314
00315 const byte_array &startup_code::byte_array_empty_array()
00316 {
00317 static byte_array __hidden_byte_array;
00318 return __hidden_byte_array;
00319 }
00320
00321 const istring &startup_code::istring_empty_string()
00322 {
00323 static istring __hidden_empty_string;
00324 return __hidden_empty_string;
00325 }
00326
00327 #undef static_class_name
00328
00329
00330 #endif //STARTUP_CODE_IMPLEMENTATION_FILE
00331