Exemple #1
0
/** 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;
}
Exemple #2
0
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);
		}
	}
}
Exemple #3
0
/** 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);
}
Exemple #4
0
/** 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();
}
Exemple #5
0
/** 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();
}
Exemple #6
0
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();
}
Exemple #9
0
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();
}
Exemple #10
0
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;
}
Exemple #11
0
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;
  }
}
Exemple #12
0
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;
}