00001
00019 #include <rtm/Manager.h>
00020 #include <rtm/ManagerConfig.h>
00021 #include <rtm/ModuleManager.h>
00022 #include <rtm/CorbaNaming.h>
00023 #include <rtm/NamingManager.h>
00024 #include <rtm/RTC.h>
00025 #include <rtm/PeriodicExecutionContext.h>
00026 #include <rtm/ExtTrigExecutionContext.h>
00027 #include <rtm/OpenHRPExecutionContext.h>
00028 #include <rtm/PeriodicECSharedComposite.h>
00029 #include <rtm/RTCUtil.h>
00030 #include <rtm/ManagerServant.h>
00031 #include <fstream>
00032 #include <iostream>
00033 #include <coil/Properties.h>
00034 #include <coil/stringutil.h>
00035 #include <coil/Signal.h>
00036 #include <coil/TimeValue.h>
00037 #include <coil/Timer.h>
00038 #include <coil/OS.h>
00039 #include <rtm/FactoryInit.h>
00040 #include <rtm/CORBA_IORUtil.h>
00041 #include <rtm/SdoServiceConsumerBase.h>
00042
00043 #if defined(minor)
00044 #undef minor
00045 #endif
00046
00047
00048 extern "C" void handler (int)
00049 {
00050 RTC::Manager::instance().terminate();
00051 }
00052
00053 namespace RTC
00054 {
00055 Manager* Manager::manager = NULL;
00056 coil::Mutex Manager::mutex;
00057
00058 Manager::InstanceName::InstanceName(RTObject_impl* comp)
00059 : m_name(comp->getInstanceName())
00060 {}
00061 Manager::InstanceName::InstanceName(const char* name)
00062 : m_name(name)
00063 {}
00064 Manager::InstanceName::InstanceName(const std::string name)
00065 : m_name(name)
00066 {}
00067 bool Manager::InstanceName::operator()(RTObject_impl* comp)
00068 {
00069 return m_name == comp->getInstanceName();
00070 }
00071
00072
00080 Manager::Manager()
00081 : m_initProc(0), m_namingManager(0), m_timer(0),
00082 m_logStreamBuf(), rtclog(&m_logStreamBuf),
00083 m_runner(0), m_terminator(0)
00084 {
00085 new coil::SignalAction((coil::SignalHandler) handler, SIGINT);
00086 }
00087
00095 Manager::Manager(const Manager& manager)
00096 : m_initProc(0), m_namingManager(0), m_timer(0),
00097 m_logStreamBuf(), rtclog(&m_logStreamBuf),
00098 m_runner(0), m_terminator(0)
00099 {
00100 new coil::SignalAction((coil::SignalHandler) handler, SIGINT);
00101 }
00102
00110 Manager* Manager::init(int argc, char** argv)
00111 {
00112
00113 if (!manager)
00114 {
00115 Guard guard(mutex);
00116 if (!manager)
00117 {
00118 manager = new Manager();
00119 manager->initManager(argc, argv);
00120 manager->initLogger();
00121 manager->initORB();
00122 manager->initNaming();
00123 manager->initFactories();
00124 manager->initExecContext();
00125 manager->initComposite();
00126 manager->initTimer();
00127 manager->initManagerServant();
00128 }
00129 }
00130 return manager;
00131 }
00132
00140 Manager& Manager::instance()
00141 {
00142
00143 if (!manager)
00144 {
00145 Guard guard(mutex);
00146 if (!manager)
00147 {
00148 manager = new Manager();
00149 manager->initManager(0, NULL);
00150 manager->initLogger();
00151 manager->initORB();
00152 manager->initNaming();
00153 manager->initFactories();
00154 manager->initExecContext();
00155 manager->initComposite();
00156 manager->initTimer();
00157 }
00158 }
00159 return *manager;
00160 }
00161
00169 void Manager::terminate()
00170 {
00171 if (m_terminator != NULL)
00172 m_terminator->terminate();
00173 }
00174
00182 void Manager::shutdown()
00183 {
00184 RTC_TRACE(("Manager::shutdown()"));
00185 shutdownComponents();
00186 shutdownNaming();
00187 shutdownORB();
00188 shutdownManager();
00189
00190 if (m_runner != NULL)
00191 {
00192 m_runner->wait();
00193 }
00194 else
00195 {
00196 join();
00197 }
00198 shutdownLogger();
00199 }
00200
00208 void Manager::join()
00209 {
00210 RTC_TRACE(("Manager::wait()"));
00211 {
00212 Guard guard(m_terminate.mutex);
00213 ++m_terminate.waiting;
00214 }
00215 while (1)
00216 {
00217 {
00218 Guard guard(m_terminate.mutex);
00219 if (m_terminate.waiting > 1) break;
00220 }
00221 coil::usleep(100000);
00222 }
00223 }
00224
00232 void Manager::setModuleInitProc(ModuleInitProc proc)
00233 {
00234 m_initProc = proc;
00235 }
00236
00244 bool Manager::activateManager()
00245 {
00246 RTC_TRACE(("Manager::activateManager()"));
00247
00248 try
00249 {
00250 if(CORBA::is_nil(this->getPOAManager()))
00251 {
00252 RTC_ERROR(("Could not get POA manager."));
00253 return false;
00254 }
00255 this->getPOAManager()->activate();
00256 RTC_TRACE(("POA Manager activated."));
00257 }
00258 catch (...)
00259 {
00260 RTC_ERROR(("POA Manager activatatin failed."));
00261 return false;
00262 }
00263
00264 std::vector<std::string> mods;
00265 mods = coil::split(m_config["manager.modules.preload"], ",");
00266
00267 for (int i(0), len(mods.size()); i < len; ++i)
00268 {
00269 std::string basename(coil::split(mods[i], ".").operator[](0));
00270 basename += "Init";
00271 try
00272 {
00273 m_module->load(mods[i], basename);
00274 }
00275 catch (ModuleManager::Error& e)
00276 {
00277 RTC_ERROR(("Module load error: %s", e.reason.c_str()));
00278 }
00279 catch (ModuleManager::SymbolNotFound& e)
00280 {
00281 RTC_ERROR(("Symbol not found: %s", e.name.c_str()));
00282 }
00283 catch (ModuleManager::ModuleNotFound& e)
00284 {
00285 RTC_ERROR(("Module not found: %s", e.name.c_str()));
00286 }
00287 catch (...)
00288 {
00289 RTC_ERROR(("Unknown Exception"));
00290 }
00291 }
00292
00293 m_config["sdo.service.consumer.available_services"]
00294 = coil::flatten(SdoServiceConsumerFactory::instance().getIdentifiers());
00295
00296 if (m_initProc != NULL)
00297 {
00298 m_initProc(this);
00299 }
00300
00301 std::vector<std::string> comp;
00302 comp = coil::split(m_config["manager.components.precreate"], ",");
00303 for (int i(0), len(comp.size()); i < len; ++i)
00304 {
00305 this->createComponent(comp[i].c_str());
00306 }
00307
00308 return true;
00309 }
00310
00318 void Manager::runManager(bool no_block)
00319 {
00320 if (no_block)
00321 {
00322 RTC_TRACE(("Manager::runManager(): non-blocking mode"));
00323 m_runner = new OrbRunner(m_pORB);
00324 m_runner->open(0);
00325 }
00326 else
00327 {
00328 RTC_TRACE(("Manager::runManager(): blocking mode"));
00329 m_pORB->run();
00330 RTC_TRACE(("Manager::runManager(): ORB was terminated"));
00331 join();
00332 }
00333 return;
00334 }
00335
00336
00337
00338
00346 void Manager::load(const char* fname, const char* initfunc)
00347 {
00348 RTC_TRACE(("Manager::load(fname = %s, initfunc = %s)",
00349 fname, initfunc));
00350 std::string file_name(fname);
00351 std::string init_func(initfunc);
00352 try
00353 {
00354 if (init_func.empty())
00355 {
00356 coil::vstring mod(coil::split(fname, "."));
00357 init_func = mod[0] + "Init";
00358 }
00359 std::string path(m_module->load(file_name, init_func));
00360 RTC_DEBUG(("module path: %s", path.c_str()));
00361 }
00362 catch (...)
00363 {
00364 RTC_ERROR(("module load error."));
00365 }
00366 return;
00367 }
00368
00376 void Manager::unload(const char* fname)
00377 {
00378 RTC_TRACE(("Manager::unload()"));
00379 m_module->unload(fname);
00380 return;
00381 }
00382
00390 void Manager::unloadAll()
00391 {
00392 RTC_TRACE(("Manager::unloadAll()"));
00393 m_module->unloadAll();
00394 return;
00395 }
00396
00404 std::vector<coil::Properties> Manager::getLoadedModules()
00405 {
00406 RTC_TRACE(("Manager::getLoadedModules()"));
00407 return m_module->getLoadedModules();
00408 }
00409
00417 std::vector<coil::Properties> Manager::getLoadableModules()
00418 {
00419 RTC_TRACE(("Manager::getLoadableModules()"));
00420 return m_module->getLoadableModules();
00421 }
00422
00423
00424
00425
00433 bool Manager::registerFactory(coil::Properties& profile,
00434 RtcNewFunc new_func,
00435 RtcDeleteFunc delete_func)
00436 {
00437 RTC_TRACE(("Manager::registerFactory(%s)", profile["type_name"].c_str()));
00438 FactoryBase* factory;
00439 factory = new FactoryCXX(profile, new_func, delete_func);
00440 try
00441 {
00442 bool ret = m_factory.registerObject(factory);
00443 if (!ret) {
00444 delete factory;
00445 return false;
00446 }
00447 return true;
00448 }
00449 catch (...)
00450 {
00451 delete factory;
00452 return false;
00453 }
00454 }
00455
00456 std::vector<coil::Properties> Manager::getFactoryProfiles()
00457 {
00458 std::vector<FactoryBase*> factories(m_factory.getObjects());
00459 std::vector<coil::Properties> props;
00460 for (int i(0), len(factories.size()); i < len; ++i)
00461 {
00462 props.push_back(factories[i]->profile());
00463 }
00464 return props;
00465 }
00466
00474 bool Manager::registerECFactory(const char* name,
00475 ECNewFunc new_func,
00476 ECDeleteFunc delete_func)
00477 {
00478 RTC_TRACE(("Manager::registerECFactory(%s)", name));
00479 try
00480 {
00481 ECFactoryBase* factory;
00482 factory = new ECFactoryCXX(name, new_func, delete_func);
00483 if(m_ecfactory.registerObject(factory))
00484 {
00485 return true;
00486 }
00487 }
00488 catch (...)
00489 {
00490 return false;
00491 }
00492 return false;
00493 }
00494
00502 std::vector<std::string> Manager::getModulesFactories()
00503 {
00504 RTC_TRACE(("Manager::getModulesFactories()"));
00505
00506 ModuleFactories m;
00507 return m_factory.for_each(m).modlist;
00508 }
00509
00510
00511
00512
00520 RTObject_impl* Manager::createComponent(const char* comp_args)
00521 {
00522 RTC_TRACE(("Manager::createComponent(%s)", comp_args));
00523
00524
00525 coil::Properties comp_prop, comp_id;
00526 if (!procComponentArgs(comp_args, comp_id, comp_prop)) return NULL;
00527
00528
00529
00530
00531
00532
00533 if (comp_prop.findNode("exported_ports") != 0)
00534 {
00535 coil::vstring exported_ports;
00536 exported_ports = coil::split(comp_prop["exported_ports"], ",");
00537
00538 std::string exported_ports_str("");
00539 for (size_t i(0), len(exported_ports.size()); i < len; ++i)
00540 {
00541 coil::vstring keyval(coil::split(exported_ports[i], "."));
00542 if (keyval.size() > 2)
00543 {
00544 exported_ports_str += (keyval[0] + "." + keyval.back());
00545 }
00546 else
00547 {
00548 exported_ports_str += exported_ports[i];
00549 }
00550
00551 if (i != exported_ports.size() - 1)
00552 {
00553 exported_ports_str += ",";
00554 }
00555 }
00556
00557 comp_prop["exported_ports"] = exported_ports_str;
00558 comp_prop["conf.default.exported_ports"] = exported_ports_str;
00559
00560 }
00561
00562
00563
00564
00565 FactoryBase* factory(m_factory.find(comp_id));
00566 if (factory == 0)
00567 {
00568 RTC_ERROR(("Factory not found: %s",
00569 comp_id["implementation_id"].c_str()));
00570
00571
00572 std::vector<coil::Properties> mp(m_module->getLoadableModules());
00573 RTC_INFO(("%d loadable modules found", mp.size()));
00574
00575 std::vector<coil::Properties>::iterator it;
00576 it = std::find_if(mp.begin(), mp.end(), ModulePredicate(comp_id));
00577 if (it == mp.end())
00578 {
00579 RTC_ERROR(("No module for %s in loadable modules list",
00580 comp_id["implementation_id"].c_str()));
00581 return 0;
00582 }
00583 if (it->findNode("module_file_name") == 0)
00584 {
00585 RTC_ERROR(("Hmm...module_file_name key not found."));
00586 return 0;
00587 }
00588
00589 RTC_INFO(("Loading module: %s", (*it)["module_file_name"].c_str()))
00590 load((*it)["module_file_name"].c_str(), "");
00591 factory = m_factory.find(comp_id);
00592 if (factory == 0)
00593 {
00594 RTC_ERROR(("Factory not found for loaded module: %s",
00595 comp_id["implementation_id"].c_str()));
00596 return 0;
00597 }
00598 }
00599
00600 coil::Properties prop;
00601 prop = factory->profile();
00602
00603 const char* inherit_prop[] = {
00604 "config.version",
00605 "openrtm.name",
00606 "openrtm.version",
00607 "os.name",
00608 "os.release",
00609 "os.version",
00610 "os.arch",
00611 "os.hostname",
00612 "corba.endpoint",
00613 "corba.id",
00614 "exec_cxt.periodic.type",
00615 "exec_cxt.periodic.rate",
00616 "exec_cxt.evdriven.type",
00617 "logger.enable",
00618 "logger.log_level",
00619 "naming.enable",
00620 "naming.type",
00621 "naming.formats",
00622 ""
00623 };
00624
00625 for (int i(0); inherit_prop[i][0] != '\0'; ++i)
00626 {
00627 const char* key(inherit_prop[i]);
00628 prop[key] = m_config[key];
00629 }
00630
00631 RTObject_impl* comp;
00632 comp = factory->create(this);
00633 if (comp == NULL)
00634 {
00635 RTC_ERROR(("RTC creation failed: %s",
00636 comp_id["implementation_id"].c_str()));
00637 return NULL;
00638 }
00639 RTC_TRACE(("RTC created: %s", comp_id["implementation_id"].c_str()));
00640
00641 prop << comp_prop;
00642
00643
00644
00645
00646
00647
00648
00649 configureComponent(comp, prop);
00650
00651
00652
00653
00654
00655 if (comp->initialize() != RTC::RTC_OK)
00656 {
00657 RTC_TRACE(("RTC initialization failed: %s",
00658 comp_id["implementation_id"].c_str()));
00659 comp->exit();
00660 RTC_TRACE(("%s was finalized", comp_id["implementation_id"].c_str()));
00661 return NULL;
00662 }
00663 RTC_TRACE(("RTC initialization succeeded: %s",
00664 comp_id["implementation_id"].c_str()));
00665
00666
00667 registerComponent(comp);
00668 return comp;
00669 }
00670
00678 bool Manager::registerComponent(RTObject_impl* comp)
00679 {
00680 RTC_TRACE(("Manager::registerComponent(%s)", comp->getInstanceName()));
00681
00682 m_compManager.registerObject(comp);
00683
00684 std::vector<std::string> names(comp->getNamingNames());
00685
00686 for (int i(0), len(names.size()); i < len; ++i)
00687 {
00688 RTC_TRACE(("Bind name: %s", names[i].c_str()));
00689 m_namingManager->bindObject(names[i].c_str(), comp);
00690 }
00691 return true;
00692 }
00693
00701 bool Manager::unregisterComponent(RTObject_impl* comp)
00702 {
00703 RTC_TRACE(("Manager::unregisterComponent(%s)", comp->getInstanceName()));
00704
00705 m_compManager.unregisterObject(comp->getInstanceName());
00706
00707 std::vector<std::string> names(comp->getNamingNames());
00708
00709 for (int i(0), len(names.size()); i < len; ++i)
00710 {
00711 RTC_TRACE(("Unbind name: %s", names[i].c_str()));
00712 m_namingManager->unbindObject(names[i].c_str());
00713 }
00714
00715 return true;
00716 }
00717
00718
00719 ExecutionContextBase* Manager::createContext(const char* ec_args)
00720 {
00721 RTC_TRACE(("Manager::createContext()"));
00722 RTC_TRACE(("ExecutionContext type: %s",
00723 m_config.getProperty("exec_cxt.periodic.type").c_str()));
00724
00725 std::string ec_id;
00726 coil::Properties ec_prop;
00727 if (!procContextArgs(ec_args, ec_id, ec_prop)) return NULL;
00728
00729 ECFactoryBase* factory(m_ecfactory.find(ec_id.c_str()));
00730 if (factory == NULL)
00731 {
00732 RTC_ERROR(("Factory not found: %s", ec_id.c_str()));
00733 return NULL;
00734 }
00735
00736 ExecutionContextBase* ec;
00737 ec = factory->create();
00738 return ec;
00739 }
00740
00748 void Manager::deleteComponent(RTObject_impl* comp)
00749 {
00750 RTC_TRACE(("deleteComponent(RTObject*)"));
00751
00752 unregisterComponent(comp);
00753
00754
00755 coil::Properties& comp_id(comp->getProperties());
00756 FactoryBase* factory(m_factory.find(comp_id));
00757 if (factory == NULL)
00758 {
00759 RTC_DEBUG(("Factory not found: %s",
00760 comp_id["implementation_id"].c_str()));
00761 return;
00762 }
00763 else
00764 {
00765 RTC_DEBUG(("Factory found: %s",
00766 comp_id["implementation_id"].c_str()));
00767 factory->destroy(comp);
00768 }
00769
00770 if (coil::toBool(m_config["manager.shutdown_on_nortcs"],
00771 "YES", "NO", true) &&
00772 !coil::toBool(m_config["manager.is_master"], "YES", "NO", false))
00773 {
00774 std::vector<RTObject_impl*> comps;
00775 comps = getComponents();
00776 if (comps.size() == 0)
00777 {
00778 shutdown();
00779 }
00780 }
00781 }
00782
00783 void Manager::deleteComponent(const char* instance_name)
00784 {
00785 RTC_TRACE(("deleteComponent(%s)", instance_name));
00786 RTObject_impl* comp;
00787 comp = m_compManager.find(instance_name);
00788 if (comp == 0)
00789 {
00790 RTC_WARN(("RTC %s was not found in manager.", instance_name));
00791 return;
00792 }
00793 deleteComponent(comp);
00794 }
00795
00803 RTObject_impl* Manager::getComponent(const char* instance_name)
00804 {
00805 RTC_TRACE(("Manager::getComponent(%s)", instance_name));
00806 return m_compManager.find(instance_name);
00807 }
00808
00816 std::vector<RTObject_impl*> Manager::getComponents()
00817 {
00818 RTC_TRACE(("Manager::getComponents()"));
00819 return m_compManager.getObjects();
00820 }
00821
00822
00823
00824
00832 CORBA::ORB_ptr Manager::getORB()
00833 {
00834 RTC_TRACE(("Manager::getORB()"));
00835 return m_pORB;
00836 }
00837
00845 PortableServer::POA_ptr Manager::getPOA()
00846 {
00847 RTC_TRACE(("Manager::getPOA()"));
00848 return m_pPOA;
00849 }
00850
00858 PortableServer::POAManager_ptr Manager::getPOAManager()
00859 {
00860 RTC_TRACE(("Manager::getPOAManager()"));
00861 return m_pPOAManager;
00862 }
00863
00864
00865
00866
00867
00868
00869
00870
00878 void Manager::initManager(int argc, char** argv)
00879 {
00880
00881 ManagerConfig config(argc, argv);
00882 config.configure(m_config);
00883 m_config["logger.file_name"] =
00884 formatString(m_config["logger.file_name"].c_str(), m_config);
00885
00886
00887 m_module = new ModuleManager(m_config);
00888
00889
00890 m_terminator = new Terminator(this);
00891 {
00892 Guard guard(m_terminate.mutex);
00893 m_terminate.waiting = 0;
00894 }
00895
00896
00897 if (coil::toBool(m_config["timer.enable"], "YES", "NO", true))
00898 {
00899 coil::TimeValue tm(0, 100000);
00900 std::string tick(m_config["timer.tick"]);
00901 if (!tick.empty())
00902 {
00903 tm = atof(tick.c_str());
00904 m_timer = new coil::Timer(tm);
00905 m_timer->start();
00906 }
00907 }
00908
00909 if (coil::toBool(m_config["manager.shutdown_auto"], "YES", "NO", true) &&
00910 !coil::toBool(m_config["manager.is_master"], "YES", "NO", false))
00911 {
00912 coil::TimeValue tm(10, 0);
00913 if (m_config.findNode("manager.auto_shutdown_duration") != NULL)
00914 {
00915 double duration;
00916 const char* s = m_config["manager.auto_shutdown_duration"].c_str();
00917 if (coil::stringTo(duration, s))
00918 {
00919 tm = duration;
00920 }
00921 }
00922 if (m_timer != NULL)
00923 {
00924 m_timer->registerListenerObj(this,
00925 &Manager::shutdownOnNoRtcs, tm);
00926 }
00927 }
00928
00929 {
00930 coil::TimeValue tm(1, 0);
00931 if (m_timer != NULL)
00932 {
00933 m_timer->registerListenerObj(this,
00934 &Manager::cleanupComponents, tm);
00935 }
00936 }
00937
00938 }
00939
00947 void Manager::shutdownManager()
00948 {
00949 RTC_TRACE(("Manager::shutdownManager()"));
00950 m_timer->stop();
00951 }
00952
00953 void Manager::shutdownOnNoRtcs()
00954 {
00955 RTC_TRACE(("Manager::shutdownOnNoRtcs()"));
00956 if (coil::toBool(m_config["manager.shutdown_on_nortcs"], "YES", "NO", true))
00957 {
00958 std::vector<RTObject_impl*> comps(getComponents());
00959 if (comps.size() == 0)
00960 {
00961 shutdown();
00962 }
00963 }
00964
00965 }
00966
00967
00968
00969
00977 bool Manager::initLogger()
00978 {
00979 rtclog.setLevel("SILENT");
00980 rtclog.setName("manager");
00981
00982 if (!coil::toBool(m_config["logger.enable"], "YES", "NO", true))
00983 {
00984 return true;
00985 }
00986
00987 std::vector<std::string> logouts;
00988 logouts = coil::split(m_config["logger.file_name"], ",");
00989
00990 for (int i(0), len(logouts.size()); i < len; ++i)
00991 {
00992 std::string logfile(logouts[i]);
00993 if (logfile == "") continue;
00994
00995
00996 if (logfile == "STDOUT" || logfile == "stdout")
00997 {
00998 m_logStreamBuf.addStream(std::cout.rdbuf());
00999 continue;
01000 }
01001
01002 std::filebuf* of = new std::filebuf();
01003 of->open(logfile.c_str(), std::ios::out | std::ios::app);
01004
01005 if (!of->is_open())
01006 {
01007 std::cerr << "Error: cannot open logfile: "
01008 << logfile << std::endl;
01009 delete of;
01010 continue;
01011 }
01012 m_logStreamBuf.addStream(of, true);
01013 m_logfiles.push_back(of);
01014 }
01015
01016
01017
01018 rtclog.setDateFormat(m_config["logger.date_format"].c_str());
01019
01020
01021 rtclog.setLevel(m_config["logger.log_level"].c_str());
01022
01023
01024 coil::toBool(m_config["logger.stream_lock"],
01025 "enable", "disable", false) ?
01026 rtclog.enableLock() : rtclog.disableLock();
01027
01028
01029 RTC_INFO(("%s", m_config["openrtm.version"].c_str()));
01030 RTC_INFO(("Copyright (C) 2003-2010"));
01031 RTC_INFO((" Noriaki Ando"));
01032 RTC_INFO((" Intelligent Systems Research Institute, AIST"));
01033 RTC_INFO(("Manager starting."));
01034 RTC_INFO(("Starting local logging."));
01035
01036 return true;;
01037 }
01038
01046 void Manager::shutdownLogger()
01047 {
01048 RTC_TRACE(("Manager::shutdownLogger()"));
01049 rtclog.flush();
01050
01051 for (int i(0), len(m_logfiles.size()); i < len; ++i)
01052 {
01053 m_logfiles[i]->close();
01054
01055 delete m_logfiles[i];
01056 }
01057 if (!m_logfiles.empty())
01058 {
01059 m_logfiles.clear();
01060 }
01061 }
01062
01063
01064
01065
01073 bool Manager::initORB()
01074 {
01075 RTC_TRACE(("Manager::initORB()"));
01076
01077 try
01078 {
01079 std::vector<std::string> args(coil::split(createORBOptions(), " "));
01080
01081 args.insert(args.begin(), "manager");
01082 char** argv = coil::toArgv(args);
01083 int argc(args.size());
01084
01085
01086 m_pORB = CORBA::ORB_init(argc, argv);
01087
01088 CORBA::Object_var obj =
01089 m_pORB->resolve_initial_references((char*)"RootPOA");
01090 m_pPOA = PortableServer::POA::_narrow(obj);
01091 if (CORBA::is_nil(m_pPOA))
01092 {
01093 RTC_ERROR(("Could not resolve RootPOA."));
01094 return false;
01095 }
01096
01097 m_pPOAManager = m_pPOA->the_POAManager();
01098
01099 #ifdef ORB_IS_OMNIORB
01100 const char* conf = "corba.alternate_iiop_addresses";
01101 if (m_config.findNode(conf) != NULL)
01102 {
01103 coil::vstring addr_list;
01104 addr_list = coil::split(m_config[conf], ",", true);
01105
01106 for (size_t i(0); i < addr_list.size(); ++i)
01107 {
01108 coil::vstring addr_port = coil::split(addr_list[i], ":");
01109 if (addr_port.size() == 2)
01110 {
01111 IIOP::Address iiop_addr;
01112 iiop_addr.host = addr_port[0].c_str();
01113 CORBA::UShort port;
01114 coil::stringTo(port, addr_port[1].c_str());
01115 iiop_addr.port = port;
01116 omniIOR::add_IIOP_ADDRESS(iiop_addr);
01117 }
01118 }
01119 }
01120 #endif // ORB_IS_OMNIORB
01121 }
01122 catch (...)
01123 {
01124 RTC_ERROR(("Exception: Caught unknown exception in initORB()." ));
01125 return false;
01126 }
01127 return true;
01128 }
01129
01137 std::string Manager::createORBOptions()
01138 {
01139 std::string opt(m_config["corba.args"]);
01140 RTC_DEBUG(("corba.args: %s", opt.c_str()));
01141
01142 RTC_DEBUG_STR((m_config));
01143
01144 coil::vstring endpoints;
01145 createORBEndpoints(endpoints);
01146 createORBEndpointOption(opt, endpoints);
01147
01148 RTC_PARANOID(("ORB options: %s", opt.c_str()));
01149 return opt;
01150 }
01151
01152 void Manager::createORBEndpoints(coil::vstring& endpoints)
01153 {
01154
01155
01156 if (m_config.findNode("corba.endpoints") != 0)
01157 {
01158 endpoints = coil::split(m_config["corba.endpoints"], ",");
01159 RTC_DEBUG(("corba.endpoints: %s", m_config["corba.endpoints"].c_str()));
01160 }
01161
01162 if (m_config.findNode("corba.endpoint") != 0)
01163 {
01164 coil::vstring tmp(coil::split(m_config["corba.endpoint"], ","));
01165 endpoints.insert(endpoints.end(), tmp.begin(), tmp.end());
01166 RTC_DEBUG(("corba.endpoint: %s", m_config["corba.endpoint"].c_str()));
01167 }
01168
01169
01170 RTC_DEBUG(("manager.is_master: %s",
01171 m_config["manager.is_master"].c_str()));
01172 if (coil::toBool(m_config["manager.is_master"], "YES", "NO", false))
01173 {
01174 std::string mm(m_config.getProperty("corba.master_manager", ":2810"));
01175 coil::vstring mmm(coil::split(mm, ":"));
01176 if (mmm.size() == 2)
01177 {
01178 endpoints.insert(endpoints.begin(), std::string(":") + mmm[1]);
01179 }
01180 else
01181 {
01182 endpoints.insert(endpoints.begin(), ":2810");
01183 }
01184 }
01185 coil::vstring tmp(endpoints);
01186 endpoints = coil::unique_sv(tmp);
01187 }
01188
01189 void Manager::createORBEndpointOption(std::string& opt,
01190 coil::vstring& endpoints)
01191 {
01192 std::string corba(m_config["corba.id"]);
01193 RTC_DEBUG(("corba.id: %s", corba.c_str()));
01194
01195 for (size_t i(0); i < endpoints.size(); ++i)
01196 {
01197 std::string& endpoint(endpoints[i]);
01198 RTC_DEBUG(("Endpoint is : %s", endpoint.c_str()));
01199 if (endpoint.find(":") == std::string::npos) { endpoint += ":"; }
01200
01201 if (corba == "omniORB")
01202 {
01203 coil::normalize(endpoint);
01204 if (coil::normalize(endpoint) == "all:")
01205 {
01206 #ifdef ORB_IS_OMNIORB
01207 #ifdef RTC_CORBA_CXXMAPPING11
01208
01209 opt += " -ORBendPointPublish all(addr)";
01210 #else
01211
01212 opt += " -ORBendPointPublishAllIFs 1";
01213 #endif // RTC_CORBA_CXXMAPPING1
01214 #endif // ORB_IS_OMNIORB
01215 }
01216 else
01217 {
01218 opt += " -ORBendPoint giop:tcp:" + endpoint;
01219 }
01220 }
01221 else if (corba == "TAO")
01222 {
01223 opt += "-ORBEndPoint iiop://" + endpoint;
01224 }
01225 else if (corba == "MICO")
01226 {
01227 opt += "-ORBIIOPAddr inet:" + endpoint;
01228 }
01229 }
01230 }
01231
01232
01240 void Manager::shutdownORB()
01241 {
01242 RTC_TRACE(("Manager::shutdownORB()"));
01243 if(CORBA::is_nil(m_pORB))
01244 {
01245 return;
01246 }
01247 try
01248 {
01249 while (m_pORB->work_pending())
01250 {
01251 RTC_PARANOID(("Pending work still exists."));
01252 if (m_pORB->work_pending())
01253 m_pORB->perform_work();
01254 }
01255 RTC_DEBUG(("No pending works of ORB. Shutting down POA and ORB."));
01256 }
01257 catch(...)
01258 {
01259 RTC_ERROR(("Caught SystemException during perform_work."));
01260 }
01261
01262 if (!CORBA::is_nil(m_pPOA))
01263 {
01264 try
01265 {
01266 if (!CORBA::is_nil(m_pPOAManager))
01267 m_pPOAManager->deactivate(false, true);
01268 RTC_DEBUG(("POA Manager was deactivated."));
01269 m_pPOA->destroy(false, true);
01270 m_pPOA = PortableServer::POA::_nil();
01271 RTC_DEBUG(("POA was destroid."));
01272 }
01273 catch (CORBA::SystemException& ex)
01274 {
01275 RTC_ERROR(("Exception cought during root POA destruction"));
01276 #ifndef ORB_IS_RTORB
01277 RTC_ERROR(("CORBA::SystemException(minor=%d)", ex.minor()));
01278 #endif // ORB_IS_RTORB
01279 }
01280 catch (...)
01281 {
01282 RTC_ERROR(("Caught unknown exception during POA destruction."));
01283 }
01284 }
01285
01286 if (!CORBA::is_nil(m_pORB))
01287 {
01288 try
01289 {
01290 m_pORB->shutdown(true);
01291 RTC_DEBUG(("ORB was shutdown."));
01292
01293 RTC_DEBUG(("ORB was destroied."));
01294 m_pORB = CORBA::ORB::_nil();
01295 }
01296 catch (CORBA::SystemException& ex)
01297 {
01298 RTC_ERROR(("Exception caught during ORB shutdown"));
01299 #ifndef ORB_IS_RTORB
01300 RTC_ERROR(("CORBA::SystemException(minodor=%d)", ex.minor()));
01301 #endif // ORB_IS_RTORB
01302 }
01303 catch (...)
01304 {
01305 RTC_ERROR(("Caught unknown exception during ORB shutdown."));
01306 }
01307 }
01308 }
01309
01310
01311
01312
01320 bool Manager::initNaming()
01321 {
01322 RTC_TRACE(("Manager::initNaming()"));
01323
01324 m_namingManager = new NamingManager(this);
01325
01326
01327 if (!coil::toBool(m_config["naming.enable"], "YES", "NO", true))
01328 {
01329 return true;
01330 }
01331
01332
01333 std::vector<std::string> meth(coil::split(m_config["naming.type"], ","));
01334
01335 for (int i(0), len_i(meth.size()); i < len_i; ++i)
01336 {
01337 std::vector<std::string> names;
01338 names = coil::split(m_config[meth[i] + ".nameservers"], ",");
01339
01340
01341 for (int j(0), len_j(names.size()); j < len_j; ++j)
01342 {
01343 RTC_TRACE(("Register Naming Server: %s/%s", \
01344 meth[i].c_str(), names[j].c_str()));
01345 m_namingManager->registerNameServer(meth[i].c_str(),
01346 names[j].c_str());
01347 }
01348 }
01349
01350
01351 if (coil::toBool(m_config["naming.update.enable"], "YES", "NO", true))
01352 {
01353 coil::TimeValue tm(10, 0);
01354 std::string intr(m_config["naming.update.interval"]);
01355 if (!intr.empty())
01356 {
01357 tm = atof(intr.c_str());
01358 }
01359 if (m_timer != NULL)
01360 {
01361 m_timer->registerListenerObj(m_namingManager,
01362 &NamingManager::update, tm);
01363 }
01364 }
01365 return true;
01366 }
01367
01375 void Manager::shutdownNaming()
01376 {
01377 RTC_TRACE(("Manager::shutdownNaming()"));
01378 m_namingManager->unbindAll();
01379 delete m_namingManager;
01380 }
01381
01382
01383
01384
01392 bool Manager::initExecContext()
01393 {
01394 RTC_TRACE(("Manager::initExecContext()"));
01395 PeriodicExecutionContextInit(this);
01396 ExtTrigExecutionContextInit(this);
01397 OpenHRPExecutionContextInit(this);
01398 return true;
01399 }
01400
01401 bool Manager::initComposite()
01402 {
01403 RTC_TRACE(("Manager::initComposite()"));
01404 PeriodicECSharedCompositeInit(this);
01405
01406 return true;
01407 }
01408
01409 bool Manager::initFactories()
01410 {
01411 RTC_TRACE(("Manager::initFactories()"));
01412 FactoryInit();
01413 return true;
01414 }
01415
01423 bool Manager::initTimer()
01424 {
01425 return true;
01426 }
01427
01428
01429 bool Manager::initManagerServant()
01430 {
01431 RTC_TRACE(("Manager::initManagerServant()"));
01432 if (!coil::toBool(m_config["manager.corba_servant"], "YES", "NO", true))
01433 {
01434 return true;
01435 }
01436 m_mgrservant = new ::RTM::ManagerServant();
01437 coil::Properties& prop(m_config.getNode("manager"));
01438 std::vector<std::string> names(coil::split(prop["naming_formats"], ","));
01439
01440 if (coil::toBool(prop["is_master"], "YES", "NO", true))
01441 {
01442 for (int i(0), len(names.size()); i < len; ++i)
01443 {
01444 std::string mgr_name(formatString(names[i].c_str(), prop));
01445 m_namingManager->bindObject(mgr_name.c_str(), m_mgrservant);
01446 }
01447 }
01448
01449 std::ifstream otherref(m_config["manager.refstring_path"].c_str());
01450 if (otherref.fail() != 0)
01451 {
01452 otherref.close();
01453 std::ofstream reffile(m_config["manager.refstring_path"].c_str());
01454 RTM::Manager_var mgr_v(RTM::Manager::
01455 _duplicate(m_mgrservant->getObjRef()));
01456 CORBA::String_var str_var = m_pORB->object_to_string(mgr_v);
01457 reffile << str_var;
01458 reffile.close();
01459 }
01460 else
01461 {
01462 std::string refstring;
01463 otherref >> refstring;
01464 otherref.close();
01465
01466 CORBA::Object_var obj = m_pORB->string_to_object(refstring.c_str());
01467 RTM::Manager_var mgr = RTM::Manager::_narrow(obj);
01468
01469
01470
01471 }
01472
01473 return true;
01474 }
01475
01483 void Manager::shutdownComponents()
01484 {
01485 RTC_TRACE(("Manager::shutdownComponents()"));
01486 std::vector<RTObject_impl*> comps;
01487 comps = m_namingManager->getObjects();
01488 for (int i(0), len(comps.size()); i < len; ++i)
01489 {
01490 try
01491 {
01492 comps[i]->exit();
01493 coil::Properties p(comps[i]->getInstanceName());
01494 p << comps[i]->getProperties();
01495 rtclog.lock();
01496 rtclog.level(Logger::RTL_PARANOID) << p;
01497 rtclog.unlock();
01498 }
01499 catch (...)
01500 {
01501 ;
01502 }
01503 }
01504 for (CORBA::ULong i(0), len(m_ecs.size()); i < len; ++i)
01505 {
01506 try{
01507 PortableServer::ObjectId_var oid = m_pPOA->servant_to_id(m_ecs[i]);
01508 m_pPOA->deactivate_object(oid);
01509 }
01510 catch (...)
01511 {
01512 ;
01513 }
01514 }
01515 }
01516
01524 void Manager::cleanupComponent(RTObject_impl* comp)
01525 {
01526 RTC_TRACE(("Manager::cleanupComponent()"));
01527 unregisterComponent(comp);
01528 }
01529
01530 void Manager::cleanupComponents()
01531 {
01532 RTC_VERBOSE(("Manager::cleanupComponents()"));
01533 Guard guard(m_finalized.mutex);
01534 RTC_VERBOSE(("%d components are marked as finalized.",
01535 m_finalized.comps.size()));
01536 for (size_t i(0); i < m_finalized.comps.size(); ++i)
01537 {
01538 deleteComponent(m_finalized.comps[i]);
01539 }
01540 m_finalized.comps.clear();
01541 }
01542
01543 void Manager::notifyFinalized(RTObject_impl* comp)
01544 {
01545 RTC_TRACE(("Manager::notifyFinalized()"));
01546 Guard guard(m_finalized.mutex);
01547 m_finalized.comps.push_back(comp);
01548 }
01549
01557 bool Manager::procComponentArgs(const char* comp_arg,
01558 coil::Properties& comp_id,
01559 coil::Properties& comp_conf)
01560 {
01561 std::vector<std::string> id_and_conf(coil::split(comp_arg, "?"));
01562
01563
01564 if (id_and_conf.size() != 1 && id_and_conf.size() != 2)
01565 {
01566 RTC_ERROR(("Invalid arguments. Two or more '?' in arg : %s", comp_arg));
01567 return false;
01568 }
01569 if (id_and_conf[0].find(":") == std::string::npos)
01570 {
01571 id_and_conf[0].insert(0, "RTC:::");
01572 id_and_conf[0] += ":";
01573 }
01574 std::vector<std::string> id(coil::split(id_and_conf[0], ":"));
01575
01576
01577
01578 if (id.size() != 5)
01579 {
01580 RTC_ERROR(("Invalid RTC id format.: %s", id_and_conf[0].c_str()));
01581 return false;
01582 }
01583
01584 const char* prof[] =
01585 {
01586 "RTC", "vendor", "category", "implementation_id", "version"
01587 };
01588
01589 if (id[0] != prof[0])
01590 {
01591 RTC_ERROR(("Invalid id type: %s", id[0].c_str()));
01592 return false;
01593 }
01594 for (int i(1); i < 5; ++i)
01595 {
01596 comp_id[prof[i]] = id[i];
01597 RTC_TRACE(("RTC basic propfile %s: %s", prof[i], id[i].c_str()));
01598 }
01599
01600 if (id_and_conf.size() == 2)
01601 {
01602 std::vector<std::string> conf(coil::split(id_and_conf[1], "&"));
01603 for (int i(0), len(conf.size()); i < len; ++i)
01604 {
01605 if (conf[i].empty()) { continue; }
01606 std::vector<std::string> keyval(coil::split(conf[i], "="));
01607 if (keyval.size() != 2) { continue; }
01608 comp_conf[keyval[0]] = keyval[1];
01609 RTC_TRACE(("RTC property %s: %s",
01610 keyval[0].c_str(), keyval[1].c_str()));
01611 }
01612 }
01613 return true;
01614 }
01615
01616 bool Manager::procContextArgs(const char* ec_args,
01617 std::string& ec_id,
01618 coil::Properties& ec_conf)
01619 {
01620 std::vector<std::string> id_and_conf(coil::split(ec_args, "?"));
01621 if (id_and_conf.size() != 1 && id_and_conf.size() != 2)
01622 {
01623 RTC_ERROR(("Invalid arguments. Two or more '?' in arg : %s", ec_args));
01624 return false;
01625 }
01626 if (id_and_conf[0].empty())
01627 {
01628 RTC_ERROR(("Empty ExecutionContext's name"));
01629 return false;
01630 }
01631 ec_id =id_and_conf[0];
01632
01633 if (id_and_conf.size() == 2)
01634 {
01635 std::vector<std::string> conf(coil::split(id_and_conf[1], "&"));
01636 for (int i(0), len(conf.size()); i < len; ++i)
01637 {
01638 std::vector<std::string> k(coil::split(conf[i], "="));
01639 ec_conf[k[0]] = k[1];
01640 RTC_TRACE(("EC property %s: %s", k[0].c_str(), k[1].c_str()));
01641 }
01642 }
01643 return true;
01644 }
01645
01653 void Manager::configureComponent(RTObject_impl* comp,
01654 const coil::Properties& prop)
01655 {
01656 std::string category(comp->getCategory());
01657 std::string type_name(comp->getTypeName());
01658 std::string inst_name(comp->getInstanceName());
01659
01660 std::string type_conf(category + "." + type_name + ".config_file");
01661 std::string name_conf(category + "." + inst_name + ".config_file");
01662
01663
01664 coil::vstring config_fname;
01665 coil::Properties type_prop, name_prop;
01666
01667
01668 if (!m_config[name_conf].empty())
01669 {
01670 std::ifstream conff(m_config[name_conf].c_str());
01671 if (!conff.fail())
01672 {
01673 name_prop.load(conff);
01674 }
01675 }
01676 if (m_config.findNode(category + "." + inst_name) != NULL)
01677 {
01678 name_prop << m_config.getNode(category + "." + inst_name);
01679 }
01680
01681 if (!m_config[type_conf].empty())
01682 {
01683 std::ifstream conff(m_config[type_conf].c_str());
01684 if (!conff.fail())
01685 {
01686 type_prop.load(conff);
01687 }
01688 }
01689 if (m_config.findNode(category + "." + type_name) != NULL)
01690 {
01691 type_prop << m_config.getNode(category + "." + type_name);
01692 }
01693
01694
01695 comp->setProperties(prop);
01696 type_prop << name_prop;
01697 comp->setProperties(type_prop);
01698
01699
01700
01701 std::string naming_formats;
01702 coil::Properties& comp_prop(comp->getProperties());
01703
01704 naming_formats += m_config["naming.formats"];
01705 if (comp_prop.findNode("naming.formats") != 0)
01706 {
01707 naming_formats = comp_prop["naming.formats"];
01708 }
01709 naming_formats = coil::flatten(coil::unique_sv(coil::split(naming_formats,
01710 ",")));
01711
01712 std::string naming_names;
01713 naming_names = formatString(naming_formats.c_str(), comp->getProperties());
01714 comp->getProperties()["naming.formats"] = naming_formats;
01715 comp->getProperties()["naming.names"] = naming_names;
01716 }
01717
01725 bool Manager::mergeProperty(coil::Properties& prop, const char* file_name)
01726 {
01727 if (file_name == NULL)
01728 {
01729 RTC_ERROR(("Invalid configuration file name."));
01730 return false;
01731 }
01732 if (file_name[0] != '\0')
01733 {
01734 std::ifstream conff(file_name);
01735 if (!conff.fail())
01736 {
01737 prop.load(conff);
01738 conff.close();
01739 return true;
01740 }
01741 }
01742 return false;
01743 }
01744
01752 std::string Manager::formatString(const char* naming_format,
01753 coil::Properties& prop)
01754 {
01755 std::string name(naming_format), str("");
01756 std::string::iterator it, it_end;
01757 int count(0);
01758
01759 it = name.begin();
01760 it_end = name.end();
01761 for ( ; it != it_end; ++it)
01762 {
01763 char c(*it);
01764 if (c == '%')
01765 {
01766 ++count;
01767 if (!(count % 2)) str.push_back((*it));
01768 }
01769 else if (c == '$')
01770 {
01771 count = 0;
01772 ++it;
01773 if (*it == '{' || *it == '(')
01774 {
01775 ++it;
01776 std::string env;
01777 for ( ; it != it_end && (*it) != '}' && (*it) != ')'; ++it)
01778 {
01779 env += *it;
01780 }
01781 char* envval = coil::getenv(env.c_str());
01782 if (envval != NULL) str += envval;
01783 }
01784 else
01785 {
01786 str.push_back(c);
01787 }
01788 }
01789 else
01790 {
01791 if (count > 0 && (count % 2))
01792 {
01793 count = 0;
01794 if (c == 'n') str += prop["instance_name"];
01795 else if (c == 't') str += prop["type_name"];
01796 else if (c == 'm') str += prop["type_name"];
01797 else if (c == 'v') str += prop["version"];
01798 else if (c == 'V') str += prop["vendor"];
01799 else if (c == 'c') str += prop["category"];
01800 else if (c == 'h') str += m_config["os.hostname"];
01801 else if (c == 'M') str += m_config["manager.name"];
01802 else if (c == 'p') str += m_config["manager.pid"];
01803 else str.push_back(c);
01804 }
01805 else
01806 {
01807 count = 0;
01808 str.push_back(c);
01809 }
01810 }
01811 }
01812 return str;
01813 }
01814
01815 };