CORBAManager.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00018 #include <assert.h>
00019 #include <iostream>
00020 #include <coil/stringutil.h>
00021 #include <doil/corba/CORBAManager.h>
00022 #include <doil/ORBManager.h>
00023 
00024 #define UNUSED_ARG(a) do {} while (&a == 0)
00025 
00026 namespace doil
00027 {
00028 namespace CORBA
00029 {
00030   // singleton pointer initializer
00031   CORBAManager* CORBAManager::manager = NULL;
00032   coil::Mutex CORBAManager::mutex;
00033 
00034 
00042   CORBAManager* CORBAManager::init(coil::Properties prop)
00043     throw()
00044   {
00045     if (!manager)
00046       {
00047         coil::Guard<coil::Mutex> guard(mutex);
00048         if (!manager)
00049           {
00050             manager = new CORBAManager();
00051             manager->initOrb(prop);
00052           }
00053       }
00054     return manager;
00055   };
00056 
00064   CORBAManager& CORBAManager::instance()
00065     throw()
00066   {
00067     coil::Properties prop;
00068     return *CORBAManager::init(prop);
00069   }
00070 
00078   const char* CORBAManager::name()
00079     throw()
00080   {
00081     return "corba";
00082   }
00083   void CORBAManager::run()
00084     throw()
00085   {
00086     // Do nothing
00087     return;
00088   }
00089 
00090 
00091   void CORBAManager::shutdown()
00092     throw()
00093   {
00094     while (m_orb->work_pending())
00095       {
00096         //        RTC_PARANOID(("Pending work still exists."));
00097         if (m_orb->work_pending())
00098           m_orb->perform_work();
00099       }
00100     
00101     if (!::CORBA::is_nil(m_poa))
00102       {
00103         try
00104           {
00105             if (!::CORBA::is_nil(m_poaManager))
00106               m_poaManager->deactivate(false, true);
00107             m_poa->destroy(false, true);
00108             m_poa = PortableServer::POA::_nil();
00109           }
00110         catch (::CORBA::SystemException& ex)
00111           {
00112           }
00113         catch (...)
00114           {
00115           }
00116       }
00117     
00118     if (!::CORBA::is_nil(m_orb))
00119       {
00120         try
00121           {
00122             m_orb->shutdown(true);
00123             m_orb = ::CORBA::ORB::_nil();
00124           }
00125         catch (::CORBA::SystemException& ex)
00126           {
00127             UNUSED_ARG(ex);
00128           }
00129         catch (...)
00130           {
00131           }
00132       }
00133     {
00134       coil::Guard<coil::Mutex> guard(mutex);
00135       delete manager;
00136       manager = NULL;
00137     }
00138   }
00139 
00140 
00148   ReturnCode_t CORBAManager::registerFactory(const char* id,
00149                                              doil::ServantNewFunc new_func,
00150                                              doil::ServantDeleteFunc delete_func)
00151     throw()
00152   {
00153     if (id == NULL) return INVALID_ARGS;
00154     if (new_func == NULL) return INVALID_ARGS;
00155     if (delete_func == NULL) return INVALID_ARGS;
00156 
00157     bool ret;
00158     ServantFactory* factory = new ServantFactory(id, new_func, delete_func);
00159     ret = m_factory.registerObject(factory);
00160     if (ret) return OK;
00161     else return ALREADY_EXISTS;
00162   }
00163 
00164 
00165   ReturnCode_t CORBAManager::registerProxyFactory(const char* id,
00166                                              doil::ProxyNewFunc new_func,
00167                                              doil::ProxyDeleteFunc delete_func)
00168     throw()
00169   {
00170     if (id == NULL) return INVALID_ARGS;
00171     if (new_func == NULL) return INVALID_ARGS;
00172     if (delete_func == NULL) return INVALID_ARGS;
00173 
00174     bool ret;
00175     ProxyFactory* factory = new ProxyFactory(id, new_func, delete_func);
00176     ret = m_factory_proxy.registerObject(factory);
00177     if (ret) return OK;
00178     else return ALREADY_EXISTS;
00179   }
00180 
00188   ReturnCode_t CORBAManager::activateObject(doil::ImplBase* impl)
00189     throw()
00190   {
00191     if (impl == NULL) return INVALID_ARGS;
00192 
00193     const char* id = impl->id();
00194     std::cout << "CORBAManager::activateObject: id " << id << std::endl;
00195     std::cout << "CORBAManager::activateObject: name " << impl->name() << std::endl;
00196     ServantFactory* factory = m_factory.find(id);
00197 
00198 #if 0
00199     if (factory != NULL)
00200     {
00201 #else
00202     // Factory NOT_FOUND
00203     if (factory == NULL) return NOT_FOUND;
00204 #endif
00205     // INVALID_ARGS
00206     try
00207       {
00208         doil::ServantBase* svt = factory->create(impl);
00209         CORBAServantBase* csvt = dynamic_cast<CORBAServantBase*>(svt);
00210         if (csvt == NULL) 
00211           {
00212             std::cout << "dynamic_cast<CORBAServantBase*> failed" << std::endl;
00213             delete svt;
00214             return INVALID_ARGS;
00215           }
00216         ReturnCode_t ret = activateObject(impl, csvt);
00217         if (ret != OK)
00218           delete svt;
00219         return ret;
00220       }
00221     catch (std::bad_alloc& e)
00222       {
00223         UNUSED_ARG(e);
00224         return INVALID_ARGS;
00225       }
00226     catch (...)
00227       {
00228         return UNKNOWN;
00229       }
00230 #if 0
00231 //
00232 //for unit tests
00233 //
00234     }
00235     else
00236     {
00237         ProxyFactory* factory_proxy = m_factory_proxy.find(id);
00238         if (factory_proxy == NULL) return NOT_FOUND;
00239         doil::ServantBase* svt = factory->create(impl);
00240     }
00241 #endif
00242     return UNKNOWN;
00243   }
00244 
00252   ReturnCode_t CORBAManager::activateObject(doil::ImplBase* impl,
00253                                             doil::ServantBase* servant)
00254     throw()
00255   {
00256     if (impl == NULL) return INVALID_ARGS;
00257     if (servant == NULL) return INVALID_ARGS;
00258 
00259     // check ID
00260     if (strcmp(impl->id(), servant->id()) != 0)
00261       return INVALID_ARGS;
00262 
00263     doil::CORBA::CORBAServantBase* svt;
00264     svt = dynamic_cast<doil::CORBA::CORBAServantBase*>(servant);
00265    
00266     if (svt == NULL) return INVALID_ARGS;
00267 
00268     // activate CORBA object
00269     ::PortableServer::ObjectId_var id = m_poa->activate_object(svt);
00270     ::CORBA::Object_ptr obj = m_poa->id_to_reference(id);
00271 
00272     Entry* entry = new Entry(impl, svt, obj);
00273     if (m_map.registerObject(entry)) return OK;
00274     return UNKNOWN;
00275   }
00276   
00284   ReturnCode_t CORBAManager::deactivateObject(doil::ImplBase* impl)
00285     throw()
00286   {
00287     if (impl == NULL) return INVALID_ARGS;
00288     return deactivateObject(impl->name());
00289   }
00290 
00298   ReturnCode_t CORBAManager::deactivateObject(const char* name)
00299     throw()
00300   {
00301     if (name == NULL) return INVALID_ARGS;
00302 
00303     Entry* entry = m_map.find(name);
00304     if (entry == NULL) return NOT_FOUND;
00305     if (::CORBA::is_nil(entry->objref_)) return NOT_FOUND;
00306 
00307     PortableServer::ObjectId_var oid;
00308     oid = m_poa->reference_to_id(entry->objref_);
00309     m_poa->deactivate_object(oid);
00310 
00311     ServantFactory* factory = m_factory.find(entry->servant_->id());
00312     factory->destroy(entry->servant_);
00313     m_map.unregisterObject(entry->impl_->name());
00314     delete entry;
00315     return OK;
00316   }
00317 
00325   doil::ImplBase* CORBAManager::getImpl(const char* name)
00326     throw()
00327   {
00328     if (name == NULL) return NULL;
00329 
00330     Entry* entry = m_map.find(name);
00331     if (entry == NULL) return NULL;
00332     return entry->impl_;
00333   }
00334 
00342   doil::ImplBase* CORBAManager::toImpl(doil::ServantBase* servant)
00343     throw()
00344   {
00345     if (servant == NULL) return NULL;
00346 
00347     std::cout << "toImpl(Servant)" << std::endl;
00348     CORBAServantBase* csvt = dynamic_cast<CORBAServantBase*>(servant);
00349 
00350     std::cout << "name: " << csvt->name() << std::endl;
00351     return getImpl(csvt->name());
00352   }
00353 
00361   doil::ServantBase* CORBAManager::getServant(const char* name)
00362     throw()
00363   {
00364     if (name == NULL) return NULL;
00365 
00366     Entry* entry = m_map.find(name);
00367     if (entry == NULL) return NULL;
00368     return entry->servant_;
00369 
00370   }
00371 
00379   doil::ServantBase* CORBAManager::toServant(doil::ImplBase* impl)
00380     throw()
00381   {
00382     if (impl == NULL) return NULL;
00383     return getServant(impl->name());
00384   }
00385 
00386   //------------------------------------------------------------
00387   // CORBAManager interfaces
00388   //------------------------------------------------------------
00396   doil::ImplBase* CORBAManager::toImpl(::CORBA::Object_ptr obj)
00397     throw()
00398   {
00399     PortableServer::ServantBase* svt = m_poa->reference_to_servant(obj);
00400     CORBAServantBase* csvt = dynamic_cast<CORBAServantBase*>(svt);
00401     if (csvt == NULL) return NULL;
00402     return toImpl(csvt);
00403   }
00404 
00412   ::CORBA::Object_ptr CORBAManager::getReference(const char* name)
00413     throw()
00414   {
00415     Entry* entry = m_map.find(name);
00416     return entry->objref_;
00417     ;
00418   }
00419 
00427   ::CORBA::Object_ptr CORBAManager::toReference(doil::ImplBase* impl)
00428     throw()
00429   {
00430     return getReference(impl->name());
00431   }
00432 
00440   ::CORBA::Object_ptr CORBAManager::toReference(doil::ServantBase* servant)
00441     throw()
00442   {
00443     return getReference(servant->name());
00444   }
00445 
00455   doil::ServantBase* CORBAManager::toServant(::CORBA::Object_ptr obj)
00456     throw()
00457   {
00458     PortableServer::ServantBase* svt = m_poa->reference_to_servant(obj);
00459     if (svt == NULL) return NULL;
00460     CORBAServantBase* csvt = dynamic_cast<CORBAServantBase*>(svt);
00461     if (csvt == NULL) return NULL;
00462     return csvt;
00463   }
00464 
00465   //------------------------------------------------------------
00466   // CORBA functions
00467   //------------------------------------------------------------
00475   ::CORBA::ORB_ptr CORBAManager::getORB()
00476     throw()
00477   {
00478     return m_orb;
00479   }
00480 
00488   ::PortableServer::POA_ptr CORBAManager::getPOA()
00489     throw()
00490   {
00491     return m_poa;
00492   }
00493 
00501   ::PortableServer::POAManager_ptr CORBAManager::getPOAManager()
00502     throw()
00503   {
00504     return m_poaManager;
00505   }
00506 
00507 
00508   //------------------------------------------------------------
00509   // protected:
00510   //------------------------------------------------------------
00511   void CORBAManager::initOrb(coil::Properties prop)
00512   {
00513     m_config = prop;
00514     std::vector<std::string> args(coil::split(createORBOptions(), " "));
00515     // TAO's ORB_init needs argv[0] as command name.
00516     args.insert(args.begin(), "manager");
00517     char** argv = coil::toArgv(args);
00518     int argc(args.size());
00519 
00520     try
00521       {
00522         
00523         m_orb = ::CORBA::ORB_init(argc, argv);
00524         assert(!::CORBA::is_nil(m_orb));
00525         
00526         ::CORBA::Object_var obj = m_orb->resolve_initial_references("RootPOA");
00527         m_poa = PortableServer::POA::_narrow(obj);
00528         assert(!::CORBA::is_nil(m_poa));
00529         m_poaManager = m_poa->the_POAManager();
00530         m_poaManager->activate();
00531       }
00532     catch (...)
00533       {
00534         return;
00535       }
00536   }
00537 
00538 
00539   std::string CORBAManager::createORBOptions()
00540   {
00541     std::string opt(m_config["args"]);
00542     std::string corba(m_config["id"]);
00543     std::string endpoint(m_config["endpoint"]);
00544     
00545     if (!endpoint.empty())
00546       {
00547         if (!opt.empty()) opt += " ";
00548         if (corba == "omniORB")   opt = "-ORBendPoint giop:tcp:" + endpoint;
00549         else if (corba == "TAO")  opt = "-ORBEndPoint iiop://" + endpoint;
00550         else if (corba == "MICO") opt = "-ORBIIOPAddr inet:" + endpoint;
00551       }
00552     return opt;
00553   }
00554 };
00555 };
00556 
00557 
00558 extern "C"
00559 {
00560   void DoilCORBAInit(coil::Properties& prop)
00561   {
00562     doil::ORBManager& mgr(doil::ORBManager::instance());
00563     mgr.addORB((doil::CORBA::CORBAManager::init(prop)));
00564   }
00565 }


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