Manager.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
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 //static sig_atomic_t g_mgrActive = true;
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     // DCL for singleton
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     // DCL for singleton
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   // Module management
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   // Component factory management
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   // Component management
00512   //============================================================
00520   RTObject_impl* Manager::createComponent(const char* comp_args)
00521   {
00522     RTC_TRACE(("Manager::createComponent(%s)", comp_args));
00523     //------------------------------------------------------------
00524     // extract "comp_type" and "comp_prop" from comp_arg
00525     coil::Properties comp_prop, comp_id;
00526     if (!procComponentArgs(comp_args, comp_id, comp_prop)) return NULL;
00527 
00528     //------------------------------------------------------------
00529     // Because the format of port-name had been changed from <port_name> 
00530     // to <instance_name>.<port_name>, the following processing was added. 
00531     // (since r1648)
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     // Create Component
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         // automatic module loading
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         // module loading
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     // Load configuration file specified in "rtc.conf"
00645     //
00646     // rtc.conf:
00647     //   [category].[type_name].config_file = file_name
00648     //   [category].[instance_name].config_file = file_name
00649     configureComponent(comp, prop);
00650 
00651     // comp->setProperties(prop);
00652     
00653     //------------------------------------------------------------
00654     // Component initialization
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     // Bind component to naming service
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     // ### NamingManager のみで代用可能
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     // ### NamingManager のみで代用可能
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     // cleanup from manager's table, and naming serivce
00752     unregisterComponent(comp);
00753 
00754     // find factory
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   // CORBA 関連
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   // Protected functions
00866   //============================================================
00867   
00868   //============================================================
00869   // Manager initialization and finalization
00870   //============================================================
00878   void Manager::initManager(int argc, char** argv)
00879   {
00880     // load configurations
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     // initialize ModuleManager
00887     m_module = new ModuleManager(m_config);
00888 
00889     // initialize Terminator
00890     m_terminator = new Terminator(this);
00891     {
00892       Guard guard(m_terminate.mutex);
00893       m_terminate.waiting = 0;
00894     }
00895     
00896     // initialize Timer
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   // Logger initialization and finalization
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         // Open logfile
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     // Set date format for log entry header
01018     rtclog.setDateFormat(m_config["logger.date_format"].c_str());
01019     
01020     // Loglevel was set from configuration file.
01021     rtclog.setLevel(m_config["logger.log_level"].c_str());
01022         
01023     // Log stream mutex locking mode
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         //        m_logStreamBuf.removeStream(m_logfiles[i]->rdbuf());
01055         delete m_logfiles[i];
01056       }
01057     if (!m_logfiles.empty())
01058       {
01059         m_logfiles.clear();
01060       }
01061   }
01062   
01063   //============================================================
01064   // ORB initialization and finalization
01065   //============================================================
01073   bool Manager::initORB()
01074   {
01075     RTC_TRACE(("Manager::initORB()"));
01076     // Initialize ORB
01077     try
01078       {
01079         std::vector<std::string> args(coil::split(createORBOptions(), " "));
01080         // TAO's ORB_init needs argv[0] as command name.
01081         args.insert(args.begin(), "manager");
01082         char** argv = coil::toArgv(args);
01083         int argc(args.size());
01084         
01085         // ORB initialization
01086         m_pORB = CORBA::ORB_init(argc, argv);
01087         // Get the RootPOA
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         // Get the POAManager
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     // corba.endpoint is obsolete
01155     // corba.endpoints with comma separated values are acceptable
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     // If this process has master manager,
01169     // master manager's endpoint inserted at the top of endpoints
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                 // omniORB 4.1 or later
01209                 opt += " -ORBendPointPublish all(addr)";
01210 #else
01211                 // omniORB 4.0
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             //m_pORB->destroy();
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   // Naming initialization and finalization
01312   //============================================================
01320   bool Manager::initNaming()
01321   {
01322     RTC_TRACE(("Manager::initNaming()"));
01323     
01324     m_namingManager = new NamingManager(this);
01325     
01326     // If NameService is disabled, return immediately
01327     if (!coil::toBool(m_config["naming.enable"], "YES", "NO", true))
01328       {
01329         return true;
01330       }
01331     
01332     // NameServer registration for each method and servers
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     // NamingManager Timer update initialization
01351     if (coil::toBool(m_config["naming.update.enable"], "YES", "NO", true))
01352       {
01353         coil::TimeValue tm(10, 0); // default interval = 10sec for safty
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   // Naming initialization and finalization
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         //        if (CORBA::is_nil(mgr)) return false;
01469         //        mgr->set_child(m_mgrservant->getObjRef());
01470         //        m_mgrservant->set_owner(mgr);
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     // arg should be "id?key0=value0&key1=value1...".
01563     // id is mandatory, conf is optional
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     // id should be devided into 1 or 5 elements
01577     // RTC:[vendor]:[category]:impl_id:[version] => 5
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     // Load "category.instance_name.config_file"
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     // Merge Properties. type_prop is merged properties
01695     comp->setProperties(prop);
01696     type_prop << name_prop;
01697     comp->setProperties(type_prop);
01698     
01699     //------------------------------------------------------------
01700     // Format component's name for NameService
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 };


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Sat Jun 8 2019 18:49:04