/** Prepare finalization. * Check if finalization at this point is possible and if so execute the * steps necessary to prepare for finalization. You also have to make sure * that this state of being able to finalize does not change until either * finalize() or cancel_finalize() is called. * * This method may return false, which means that at this point the thread * cannot be stopped safely. This might be due to a critical internal * condition that may hurt hardware if turned of right now. In this case * a logger should be used to log the reason for the failure. The check is * implemented in prepare_finalize_user(), which the user has to implement * if he needs special treatment. * * Even if the finalization is said to be unsafe and false is returned, the * caller may still decide to finalize this thread, for example if all * threads are shut down on application exit. So you may not rely on the * fact that the thread is not stopped if you return false. * * You may not override this method. * * It is guaranteed that this method is only called for a running thread. * * @return true if the thread can be stopped and destroyed safely, false if * it has to stay alive * @see finalize() * @see cancel_finalize() */ bool Thread::prepare_finalize() { if ( ! __started ) { throw CannotFinalizeThreadException("Thread has not been started"); } if ( finalize_prepared ) { throw CannotFinalizeThreadException("prepare_finalize() has already been called"); } __prepfin_hold_mutex->lock(); while (__prepfin_hold) { __prepfin_hold_waitcond->wait(); } if (! __prepfin_conc_loop) { loopinterrupt_antistarve_mutex->lock(); loop_mutex->lock(); } finalize_prepared = true; bool prepared = prepare_finalize_user(); if (! __prepfin_conc_loop) { loop_mutex->unlock(); loopinterrupt_antistarve_mutex->unlock(); } __prepfin_hold_mutex->unlock(); return prepared; }
void AspectManager::finalize(Thread *thread) { Aspect *aspected_thread = dynamic_cast<Aspect *>(thread); if (aspected_thread != NULL) { // thread has aspects to finalize const std::list<const char *> &aspects = aspected_thread->get_aspects(); std::list<const char *>::const_iterator i; for (i = aspects.begin(); i != aspects.end(); ++i) { if (inifins_.find(*i) == inifins_.end()) { throw CannotFinalizeThreadException("Thread '%s' has the %s, " "but no finalizer is known.", thread->name(), *i); } inifins_[*i]->finalize(thread); } // We remove the threads afterwards, because we assume that the plugin // will not be unloaded, if the finalization throws an exception. for (i = aspects.begin(); i != aspects.end(); ++i) { threads_[*i].remove(thread); } } }
/** Remove the given thread. * The thread manager tries to finalize and stop the thread and then removes the * thread from the internal structures. * * This may fail if the thread cannot be finalized, for * example if prepare_finalize() returns false or if the thread finalizer cannot * finalize the thread. In this case a CannotFinalizeThreadException is thrown. * * @param thread thread to remove. * @exception CannotFinalizeThreadException At least one thread cannot be safely * finalized */ void ThreadManager::remove_maybelocked(Thread *thread, bool lock) { if ( thread == NULL ) return; if ( ! (__initializer && __finalizer) ) { throw NullPointerException("ThreadManager: initializer/finalizer not set"); } MutexLocker locker(__threads.mutex(), lock); try { if ( ! thread->prepare_finalize() ) { thread->cancel_finalize(); throw CannotFinalizeThreadException("Thread '%s'cannot be finalized", thread->name()); } } catch (CannotFinalizeThreadException &e) { e.append("ThreadManager cannot stop thread '%s'", thread->name()); thread->cancel_finalize(); throw; } thread->cancel(); thread->join(); __finalizer->finalize(thread); thread->finalize(); internal_remove_thread(thread); }
/** Remove the given threads. * The thread manager tries to finalize and stop the threads and then removes the * threads from the internal structures. * * This may fail if at least one thread of the given list cannot be finalized, for * example if prepare_finalize() returns false or if the thread finalizer cannot * finalize the thread. In this case a CannotFinalizeThreadException is thrown. * * @param tl threads to remove. * @exception CannotFinalizeThreadException At least one thread cannot be safely * finalized * @exception ThreadListNotSealedException if the given thread lits tl is not * sealed the thread manager will refuse to remove it */ void ThreadManager::remove_maybelocked(ThreadList &tl, bool lock) { if ( ! (__initializer && __finalizer) ) { throw NullPointerException("ThreadManager: initializer/finalizer not set"); } if ( ! tl.sealed() ) { throw ThreadListNotSealedException("(ThreadManager) Cannot remove unsealed thread " "list. Not accepting unsealed list '%s' for removal", tl.name()); } tl.lock(); MutexLocker locker(__threads.mutex(), lock); try { if ( ! tl.prepare_finalize(__finalizer) ) { tl.cancel_finalize(); tl.unlock(); throw CannotFinalizeThreadException("One or more threads in list '%s' cannot be " "finalized", tl.name()); } } catch (CannotFinalizeThreadException &e) { tl.unlock(); throw; } catch (Exception &e) { tl.unlock(); e.append("One or more threads in list '%s' cannot be finalized", tl.name()); throw CannotFinalizeThreadException(e); } tl.stop(); try { tl.finalize(__finalizer); } catch (Exception &e) { tl.unlock(); throw; } for (ThreadList::iterator i = tl.begin(); i != tl.end(); ++i) { internal_remove_thread(*i); } tl.unlock(); }
/** Cancel finalization. * This means that something has happened (for example another thread from * the same plugin) has indicated that it can not be finalized. In that case * also this thread has to continue to run and the finalization is canceled. * The thread is expected to run after the finalization has been canceled as * if the finalization was never tried. * * This is only called on a running thread after prepare_finalization() has * been called. * * @see prepare_finalize() * @see finalize() */ void Thread::cancel_finalize() { if ( ! __started ) { throw CannotFinalizeThreadException("Cannot cancel finalize, thread has not been started"); } loop_mutex->lock(); finalize_prepared = false; loop_mutex->unlock(); }
void WebviewAspectIniFin::finalize(Thread *thread) { WebviewAspect *webview_thread; webview_thread = dynamic_cast<WebviewAspect *>(thread); if (webview_thread == NULL) { throw CannotFinalizeThreadException("Thread '%s' claims to have the " "WebviewAspect, but RTTI says it " "has not. ", thread->name()); } }
void ROSAspectIniFin::finalize(Thread *thread) { ROSAspect *ros_thread; ros_thread = dynamic_cast<ROSAspect *>(thread); if (ros_thread == NULL) { throw CannotFinalizeThreadException("Thread '%s' claims to have the " "ROSAspect, but RTTI says it " "has not. ", thread->name()); } ros_thread->finalize_ROSAspect(); }
void NavGraphAspectIniFin::finalize(Thread *thread) { NavGraphAspect *navgraph_thread; navgraph_thread = dynamic_cast<NavGraphAspect *>(thread); if (navgraph_thread == NULL) { throw CannotFinalizeThreadException("Thread '%s' claims to have the " "NavGraphAspect, but RTTI says it " "has not. ", thread->name()); } navgraph_thread->navgraph.clear(); }
void TransformAspectIniFin::finalize(Thread *thread) { TransformAspect *transform_thread; transform_thread = dynamic_cast<TransformAspect *>(thread); if (transform_thread == NULL) { throw CannotFinalizeThreadException("Thread '%s' claims to have the " "TransformAspect, but RTTI says it " "has not. ", thread->name()); } transform_thread->finalize_TransformAspect(); }
void BlackBoardAspectIniFin::finalize(Thread *thread) { BlackBoardAspect *blackboard_thread; blackboard_thread = dynamic_cast<BlackBoardAspect *>(thread); if (blackboard_thread == NULL) { throw CannotFinalizeThreadException("Thread '%s' claims to have the " "BlackBoardAspect, but RTTI says it " "has not. ", thread->name()); } delete blackboard_thread->blackboard; blackboard_thread->blackboard = NULL; }
void LoggerAspectIniFin::finalize(Thread *thread) { LoggerAspect *logger_thread; logger_thread = dynamic_cast<LoggerAspect *>(thread); if (logger_thread == 0) { throw CannotFinalizeThreadException("Thread '%s' claims to have the " "LoggerAspect, but RTTI says it " "has not. ", thread->name()); } try { __employer->remove_logger(logger_thread->get_logger()); } catch (Exception &e) { CannotFinalizeThreadException ce("Failed to remove logger"); ce.append(e); throw; } }
bool AspectManager::prepare_finalize(Thread *thread) { Aspect *aspected_thread = dynamic_cast<Aspect *>(thread); if (aspected_thread != NULL) { // thread has aspects to finalize const std::list<const char *> &aspects = aspected_thread->get_aspects(); std::list<const char *>::const_iterator i; for (i = aspects.begin(); i != aspects.end(); ++i) { if (inifins_.find(*i) == inifins_.end()) { throw CannotFinalizeThreadException("Thread '%s' has the %s, " "but no finalizer is known.", thread->name(), *i); } if (!inifins_[*i]->prepare_finalize(thread)) { return false; } } } return true; }