Changeset 10539
- Timestamp:
- Jun 7, 2015, 12:10:24 PM (10 years ago)
- Location:
- code/branches/core7/src/libraries/core
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/core7/src/libraries/core/CoreStaticInitializationHandler.cc
r10538 r10539 29 29 #include "CoreStaticInitializationHandler.h" 30 30 31 #include "CoreIncludes.h" 31 32 #include "module/ModuleInstance.h" 32 33 #include "class/IdentifierManager.h" 34 #include "object/Iterator.h" 33 35 34 36 namespace orxonox … … 53 55 void CoreStaticInitializationHandler::loadInstances(ModuleInstance* module) 54 56 { 55 // the order of initialization is important 57 // the order of initialization is important: handlers > identifiers > singletons > everything else 56 58 module->loadAllStaticallyInitializedInstances(StaticInitialization::STATIC_INITIALIZATION_HANDLER); 57 59 module->loadAllStaticallyInitializedInstances(StaticInitialization::IDENTIFIER); … … 72 74 module->unloadAllStaticallyInitializedInstances(StaticInitialization::COMMAND_LINE_ARGUMENT); 73 75 module->unloadAllStaticallyInitializedInstances(StaticInitialization::SCOPED_SINGLETON_WRAPPER); 76 77 // until now every object (including singletons) of the unloaded identifiers should have been destroyed in a controlled manner. 78 // every remaining object is now destroyed in random order. 79 this->destroyObjects(module); 80 81 // all objects are gone now and we can unload identifiers 74 82 module->unloadAllStaticallyInitializedInstances(StaticInitialization::IDENTIFIER); 75 83 module->unloadAllStaticallyInitializedInstances(StaticInitialization::STATIC_INITIALIZATION_HANDLER); 76 84 } 85 86 void CoreStaticInitializationHandler::destroyObjects(ModuleInstance* module) 87 { 88 // collect all identifiers that are about to be unloaded 89 std::set<Identifier*> identifiers; 90 const std::set<StaticallyInitializedInstance*>& instances = module->getInstances(StaticInitialization::IDENTIFIER); 91 for (std::set<StaticallyInitializedInstance*>::const_iterator it = instances.begin(); it != instances.end(); ++it) 92 identifiers.insert(&static_cast<StaticallyInitializedIdentifier*>(*it)->getIdentifier()); 93 94 // destroy objects. some objects may survive this at first because they still have smart pointers pointing at them. this is 95 // ok as long as those smart pointers are held by objects that are also about to be destroyed in the same loop. this means 96 // that objects within one module may reference each other by smart pointers. but it is not allowed that objects from another 97 // module (which is not unloaded) uses smart pointers to point at objects inside the unloaded module. this will lead to a crash. 98 for (std::set<Identifier*>::iterator it = identifiers.begin(); it != identifiers.end(); ++it) 99 (*it)->destroyObjects(); 100 101 // check if all objects were really destroyed. this is not the case if an object is referenced by a smart pointer from another 102 // module (or if two objects inside this module reference each other). this will lead to a crash and must be fixed (e.g. by 103 // changing object dependencies; or by changing the logic that allows modules to be unloaded). 104 for (std::set<Identifier*>::iterator it = identifiers.begin(); it != identifiers.end(); ++it) 105 { 106 ObjectListBase* objectList = Context::getRootContext()->getObjectList(*it); 107 if (objectList->size() > 0) 108 { 109 orxout(internal_error) << "There are still " << objectList->size() << " objects of type " << (*it)->getName() 110 << " after unloading the Identifier. This may lead to a crash" << endl; 111 } 112 } 113 114 // destroy object-lists in all contexts 115 for (std::set<Identifier*>::iterator it_identifier = identifiers.begin(); it_identifier != identifiers.end(); ++it_identifier) 116 { 117 // only do this if the Identifier is not a Context itself; otherwise we delete the list we're iterating over 118 if (!(*it_identifier)->isExactlyA(Class(Context))) 119 { 120 // iterate over all contexts 121 for (ObjectList<Context>::iterator it_context = ObjectList<Context>::begin(); it_context != ObjectList<Context>::end(); ++it_context) 122 it_context->destroyObjectList((*it_identifier)); 123 } 124 } 125 } 77 126 } -
code/branches/core7/src/libraries/core/CoreStaticInitializationHandler.h
r10535 r10539 56 56 void initInstances(ModuleInstance* module); 57 57 58 void destroyObjects(ModuleInstance* module); 59 58 60 bool bInitInstances_; 59 61 }; -
code/branches/core7/src/libraries/core/class/Identifier.h
r10537 r10539 152 152 inline bool isInitialized() const { return this->bInitialized_; } 153 153 154 virtual void destroyObjects() = 0; 155 156 virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const = 0; 157 158 static bool initConfigValues_s; // TODO: this is a hack - remove it as soon as possible 159 154 160 155 161 ///////////////////////////// … … 215 221 XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname); 216 222 217 virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const = 0;218 219 static bool initConfigValues_s; // TODO: this is a hack - remove it as soon as possible220 221 223 protected: 222 224 virtual void createSuperFunctionCaller() const = 0; … … 297 299 { return dynamic_cast<T*>(object) != 0; } 298 300 301 virtual void destroyObjects(); 302 299 303 static ClassIdentifier<T>* getIdentifier(); 300 304 … … 307 311 void addObjectToList(T* object, Listable*); 308 312 void addObjectToList(T* object, Identifiable*); 313 314 void destroyObjects(Listable*); 315 void destroyObjects(void*); 316 317 void destroyObject(Destroyable* object); 318 void destroyObject(void* object); 309 319 310 320 void updateConfigValues(bool updateChildren, Listable*) const; … … 389 399 { 390 400 // no action 401 } 402 403 /** 404 * @brief Destroy all objects of this class (must be Listable). 405 * Destroyables are destroyed with destroy(), all other classes with delete. 406 */ 407 template <class T> 408 void ClassIdentifier<T>::destroyObjects() 409 { 410 this->destroyObjects((T*)0); 411 } 412 413 /** 414 * @brief Only searches and destroys objects if is a @ref Listable 415 */ 416 template <class T> 417 void ClassIdentifier<T>::destroyObjects(Listable*) 418 { 419 ObjectListBase* objectList = Context::getRootContext()->getObjectList(this); 420 ObjectListElement<T>* begin = static_cast<ObjectListElement<T>*>(objectList->begin()); 421 ObjectListElement<T>* end = static_cast<ObjectListElement<T>*>(objectList->end()); 422 for (typename ObjectList<T>::iterator it = begin; it != end; ) 423 this->destroyObject(*(it++)); 424 } 425 426 template <class T> 427 void ClassIdentifier<T>::destroyObjects(void*) 428 { 429 // no action 430 } 431 432 /** 433 * @brief Call 'object->destroy()' for Destroyables and 'delete object' for all other types. 434 */ 435 template <class T> 436 void ClassIdentifier<T>::destroyObject(Destroyable* object) 437 { 438 object->destroy(); 439 } 440 441 template <class T> 442 void ClassIdentifier<T>::destroyObject(void* object) 443 { 444 delete static_cast<Identifiable*>(object); 391 445 } 392 446 -
code/branches/core7/src/libraries/core/module/ModuleInstance.h
r10535 r10539 52 52 void unloadAllStaticallyInitializedInstances(StaticInitialization::Type type); 53 53 54 inline const std::set<StaticallyInitializedInstance*>& getInstances(StaticInitialization::Type type) 55 { return this->staticallyInitializedInstancesByType_[type]; } 56 54 57 void deleteAllStaticallyInitializedInstances(); 55 58 -
code/branches/core7/src/libraries/core/object/Context.cc
r9667 r10539 97 97 return this->objectLists_[classID]; 98 98 } 99 100 void Context::destroyObjectList(const Identifier* identifier) 101 { 102 ObjectListBase* objectList = this->getObjectList(identifier); 103 delete objectList; 104 this->objectLists_[identifier->getClassID()] = NULL; 105 } 99 106 } -
code/branches/core7/src/libraries/core/object/Context.h
r9667 r10539 71 71 } 72 72 73 void destroyObjectList(const Identifier* identifier); 74 73 75 private: 74 76 Context* parentContext_;
Note: See TracChangeset
for help on using the changeset viewer.