Skip to content
Snippets Groups Projects
ApplicationModule.cc 2.66 KiB
Newer Older
/*
 * ApplicationModule.cc
 *
 *  Created on: Jun 17, 2016
 *      Author: Martin Hierholzer
 */

/*********************************************************************************************************************/

  ApplicationModule::ApplicationModule(EntityOwner *owner, const std::string &name, const std::string &description,
          bool eliminateHierarchy, const std::unordered_set<std::string> &tags)
  : ModuleImpl(owner,name,description,eliminateHierarchy,tags)
  {
    if(!dynamic_cast<ModuleGroup*>(owner) && !dynamic_cast<Application*>(owner)) {
      throw ChimeraTK::logic_error("ApplicationModules must be owned either by ModuleGroups or the Application!");
    if(name.find_first_of("/") != std::string::npos) {
      throw ChimeraTK::logic_error("Module names must not contain slashes: '"+name+" owned by '"
                                   +owner->getQualifiedName()+"'.");
    }
  }

/*********************************************************************************************************************/

    // start the module thread
    assert(!moduleThread.joinable());
    moduleThread = boost::thread(&ApplicationModule::mainLoopWrapper, this);
/*********************************************************************************************************************/

  void ApplicationModule::terminate() {
    if(moduleThread.joinable()) {
      moduleThread.interrupt();
      // try joining the thread
      while(!moduleThread.try_join_for(boost::chrono::milliseconds(10))) {
        // if thread is not yet joined, send interrupt() to all variables.
        for(auto &var : getAccessorListRecursive()) {
          if(var.getDirection() != VariableDirection::consuming) continue;
          var.getAppAccessorNoType().getHighLevelImplElement()->interrupt();
        }
        // it may not suffice to send interrupt() once, as the exception might get overwritten in the queue, thus we
        // repeat this until the thread was joined.
/*********************************************************************************************************************/

  ApplicationModule::~ApplicationModule() {
    assert(!moduleThread.joinable());

/*********************************************************************************************************************/

    Application::registerThread("AM_"+getName());
    Application::testableModeLock("start");
    Application::testableModeUnlock("terminate");