void AspectManager::init(Thread *thread) { Aspect *aspected_thread = dynamic_cast<Aspect *>(thread); if (aspected_thread != NULL) { // thread has aspects to initialize const std::list<const char *> &aspects = aspected_thread->get_aspects(); std::list<const char *> initialized; try { std::list<const char *>::const_iterator i; for (i = aspects.begin(); i != aspects.end(); ++i) { if (inifins_.find(*i) == inifins_.end()) { throw CannotInitializeThreadException("Thread '%s' has the %s, " "but no initializer is known.", thread->name(), *i); } inifins_[*i]->init(thread); initialized.push_back(*i); } for (i = aspects.begin(); i != aspects.end(); ++i) { threads_[*i].push_back(thread); } } catch (CannotInitializeThreadException &e) { std::list<const char *>::const_reverse_iterator i; for (i = initialized.rbegin(); i != initialized.rend(); ++i) { inifins_[*i]->finalize(thread); } throw; } catch (Exception &e) { std::list<const char *>::const_reverse_iterator i; for (i = initialized.rbegin(); i != initialized.rend(); ++i) { inifins_[*i]->finalize(thread); } CannotInitializeThreadException ce; ce.append(e); throw ce; } } }
/** Initialize threads. * The threads are being initialized. * This operation is carried out unlocked. Lock it from the outside if needed. * This is done because it is likely that this will be chained with other * actions that require locking, thus you can lock the whole operation. * @param initializer thread initializer to use * @param finalizer finalizer to use to finalize threads that have been successfully * initialized before one thread failed. * @exception CannotInitializeThreadException thrown if at least one of the * threads in this list could not be initialized. */ void ThreadList::init(ThreadInitializer *initializer, ThreadFinalizer *finalizer) { CannotInitializeThreadException cite; ThreadList initialized_threads; bool success = true; for (ThreadList::iterator i = begin(); i != end(); ++i) { // if initializer fails, we assume it handles finalization try { initializer->init(*i); } catch (Exception &e) { cite.append("Initialized failed to initialize thread '%s'", (*i)->name()); cite.append(e); success = false; break; } // if the thread's init() method fails, we need to finalize that very // thread only with the finalizer, already initialized threads muts be // fully finalized try { (*i)->init(); initialized_threads.push_back(*i); } catch (CannotInitializeThreadException &e) { notify_of_failed_init(); cite.append("Initializing thread '%s' in list '%s' failed", (*i)->name(), __name); cite.append(e); finalizer->finalize(*i); success = false; break; } catch (Exception &e) { notify_of_failed_init(); cite.append("Could not initialize thread '%s'", (*i)->name()); cite.append(e); finalizer->finalize(*i); success = false; break; } catch (std::exception &e) { notify_of_failed_init(); cite.append("Could not initialize thread '%s'", (*i)->name()); cite.append("Caught std::exception or derivative: %s", e.what()); finalizer->finalize(*i); success = false; break; } catch (...) { notify_of_failed_init(); cite.append("Could not initialize thread '%s'", (*i)->name()); cite.append("Unknown exception caught"); finalizer->finalize(*i); success = false; break; } } if ( ! success ) { initialized_threads.finalize(finalizer); throw cite; } }