From: caremoli Date: Sun, 1 Jun 2008 16:50:49 +0000 (+0000) Subject: CCAR: add an experimental feature : standalone component X-Git-Tag: CCARexeccompoEnd X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=fc29dd94e72b4f03c436b090018d208e816e3931;p=modules%2Fkernel.git CCAR: add an experimental feature : standalone component A standalone component is implemented in an executable that is launched by the container. The create_component_instance has been modified : after trying to load a shared lib or a python module, it tries to launch the executable component.exe. This development is between tags CCARexeccompoStart and CCARexeccompoEnd --- diff --git a/src/Container/Component_i.cxx b/src/Container/Component_i.cxx index cfeeefc9b..867411196 100644 --- a/src/Container/Component_i.cxx +++ b/src/Container/Component_i.cxx @@ -106,6 +106,7 @@ Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb, _poa = PortableServer::POA::_duplicate(poa); _contId = contId ; CORBA::Object_var o = _poa->id_to_reference(*contId); // container ior... + _container=Engines::Container::_narrow(o); const CORBA::String_var ior = _orb->object_to_string(o); _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession", _instanceName.c_str()); @@ -114,6 +115,56 @@ Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb, //SCRUTE(pd_refCount); } +//============================================================================= +/*! + * Standard Constructor for standalone Component, used in derived class + * Connection to Registry and Notification + * \param orb Object Request broker given by Container + * \param poa Portable Object Adapter from Container (normally root_poa) + * \param container container CORBA reference + * \param instanceName unique instance name for this object (see Container_i) + * \param interfaceName component class name + * \param notif use of notification + */ +//============================================================================= + +Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif) : + _instanceName(instanceName), + _interfaceName(interfaceName), + _myConnexionToRegistry(0), + _notifSupplier(0), + _ThreadId(0) , + _ThreadCpuUsed(0) , + _Executed(false) , + _graphName("") , + _nodeName(""), + _studyId(-1), + _CanceledThread(false) +{ + MESSAGE("Component constructor with instanceName "<< _instanceName); + _orb = CORBA::ORB::_duplicate(orb); + _poa = PortableServer::POA::_duplicate(poa); + _container=Engines::Container::_duplicate(container); + try + { + _contId=_poa->reference_to_id(container); + } + catch(PortableServer::POA::WrongAdapter) + { + //not created by this poa + _contId = 0; + } + const CORBA::String_var ior = _orb->object_to_string(_container); + _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession", _instanceName.c_str()); + _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif); +} + + //============================================================================= /*! * Standard constructor for parallel component @@ -261,9 +312,7 @@ void Engines_Component_i::destroy() Engines::Container_ptr Engines_Component_i::GetContainerRef() { - // MESSAGE("Engines_Component_i::GetContainerRef"); - CORBA::Object_var o = _poa->id_to_reference(*_contId) ; - return Engines::Container::_narrow(o); + return Engines::Container::_duplicate(_container); } //============================================================================= diff --git a/src/Container/Container_i.cxx b/src/Container/Container_i.cxx index 41e2b5b61..0095b0bc5 100644 --- a/src/Container/Container_i.cxx +++ b/src/Container/Container_i.cxx @@ -337,6 +337,78 @@ void Engines_Container_i::Shutdown() } } +/* int checkifexecutable(const char *filename) + * + * Return non-zero if the name is an executable file, and + * zero if it is not executable, or if it does not exist. + */ + +int checkifexecutable(const char *filename) +{ + int result; + struct stat statinfo; + + result = stat(filename, &statinfo); + if (result < 0) return 0; + if (!S_ISREG(statinfo.st_mode)) return 0; + + if (statinfo.st_uid == geteuid()) return statinfo.st_mode & S_IXUSR; + if (statinfo.st_gid == getegid()) return statinfo.st_mode & S_IXGRP; + return statinfo.st_mode & S_IXOTH; +} + + +/* int findpathof(char *pth, const char *exe) + * + * Find executable by searching the PATH environment variable. + * + * const char *exe - executable name to search for. + * char *pth - the path found is stored here, space + * needs to be available. + * + * If a path is found, returns non-zero, and the path is stored + * in pth. If exe is not found returns 0, with pth undefined. + */ + +int findpathof(char *pth, const char *exe) +{ + char *searchpath; + char *beg, *end; + int stop, found; + int len; + + if (strchr(exe, '/') != NULL) { + if (realpath(exe, pth) == NULL) return 0; + return checkifexecutable(pth); + } + + searchpath = getenv("PATH"); + if (searchpath == NULL) return 0; + if (strlen(searchpath) <= 0) return 0; + + beg = searchpath; + stop = 0; found = 0; + do { + end = strchr(beg, ':'); + if (end == NULL) { + stop = 1; + strncpy(pth, beg, PATH_MAX); + len = strlen(pth); + } else { + strncpy(pth, beg, end - beg); + pth[end - beg] = '\0'; + len = end - beg; + } + if (pth[len - 1] != '/') strncat(pth, "/", 1); + strncat(pth, exe, PATH_MAX - len); + found = checkifexecutable(pth); + if (!stop) beg = end + 1; + } while (!stop && !found); + + return found; +} + + //============================================================================= /*! @@ -424,9 +496,16 @@ Engines_Container_i::load_component_Library(const char* componentName) return true; } } + // Try to find an executable + std::string executable=aCompName+".exe"; + char path[PATH_MAX+1]; + if (findpathof(path, executable.c_str())) + return true; + INFOS( "Impossible to load component: " << componentName ); INFOS( "Can't load shared library: " << impl_name ); INFOS( "Can't import Python module: " << componentName ); + INFOS( "Can't execute program: " << executable ); return false; } @@ -504,12 +583,7 @@ Engines_Container_i::create_component_instance(const char*genericRegisterName, #else string impl_name = genericRegisterName +string("Engine.dll"); #endif - if (_library_map.count(impl_name) == 0) - { - INFOS("shared library " << impl_name <<" must be loaded before creating instance"); - return Engines::Component::_nil() ; - } - else + if (_library_map.count(impl_name) != 0) // C++ component { void* handle = _library_map[impl_name]; iobject = createInstance(genericRegisterName, @@ -517,6 +591,96 @@ Engines_Container_i::create_component_instance(const char*genericRegisterName, studyId); return iobject._retn(); } + + // If it's not a Python or a C++ component try to launch a standalone component + // in a sub directory + // This component is implemented in an executable with name genericRegisterName.exe + // It must register itself in Naming Service. The container waits some time (10 s max) + // it's registration. + + _numInstanceMutex.lock() ; // lock on the instance number + _numInstance++ ; + int numInstance = _numInstance ; + _numInstanceMutex.unlock() ; + + char aNumI[12]; + sprintf( aNumI , "%d" , numInstance ) ; + string instanceName = aCompName + "_inst_" + aNumI ; + string component_registerName = _containerName + "/" + instanceName; + + //check if an entry exist in naming service + CORBA::Object_var nsobj = _NS->Resolve(component_registerName.c_str()); + if ( !CORBA::is_nil(nsobj) ) + { + // unregister the registered component + _NS->Destroy_Name(component_registerName.c_str()); + //kill or shutdown it ??? + } + + // first arg container ior string + // second arg container name + // third arg instance name + + Engines::Container_var pCont= _this(); + CORBA::String_var sior = _orb->object_to_string(pCont); + + std::string command; + command="mkdir -p "; + command+=instanceName; + command+=";cd "; + command+=instanceName; + command+=";"; + command+=genericRegisterName ; + command+=".exe"; + command+=" "; + command+= sior; // container ior string + command+=" "; + command+=_containerName; //container name + command+=" "; + command+=instanceName; //instance name + command+=" &"; + MESSAGE("SALOME_Container::create_component_instance command=" << command); + // launch component with a system call + int status=system(command.c_str()); + + if (status == -1) + { + MESSAGE("SALOME_Container::create_component_instance system failed " << "(system command status -1)"); + return Engines::Component::_nil(); + } + else if (WEXITSTATUS(status) == 217) + { + MESSAGE("SALOME_Container::create_component_instance system failed " << "(system command status 217)"); + return Engines::Component::_nil(); + } + else + { + int count=10; + CORBA::Object_var obj = CORBA::Object::_nil() ; + while ( CORBA::is_nil(obj) && count ) + { +#ifndef WNT + sleep( 1 ) ; +#else + Sleep(1000); +#endif + count-- ; + MESSAGE( count << ". Waiting for component " << genericRegisterName); + obj = _NS->Resolve(component_registerName.c_str()); + } + + if(CORBA::is_nil(obj)) + { + MESSAGE("SALOME_Container::create_component_instance failed"); + return Engines::Component::_nil(); + } + else + { + MESSAGE("SALOME_Container::create_component_instance successful"); + iobject=Engines::Component::_narrow(obj); + return iobject._retn(); + } + } } //============================================================================= diff --git a/src/Container/SALOME_Component_i.hxx b/src/Container/SALOME_Component_i.hxx index 03234c307..3d49b89c5 100644 --- a/src/Container/SALOME_Component_i.hxx +++ b/src/Container/SALOME_Component_i.hxx @@ -61,6 +61,13 @@ public: const char *instanceName, const char *interfaceName, bool notif = false); + //Constructor for standalone component + Engines_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif = false); // Consructeur pour composant parallele: ne pas faire appel au registry Engines_Component_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, @@ -147,6 +154,7 @@ protected: PortableServer::POA_var _poa; PortableServer::ObjectId * _id; PortableServer::ObjectId * _contId; + Engines::Container_var _container; Engines_Component_i * _thisObj ; RegistryConnexion *_myConnexionToRegistry; NOTIFICATION_Supplier* _notifSupplier; diff --git a/src/DSC/DSC_Basic/DSC_i.cxx b/src/DSC/DSC_Basic/DSC_i.cxx index bf67a554c..2daa87423 100644 --- a/src/DSC/DSC_Basic/DSC_i.cxx +++ b/src/DSC/DSC_Basic/DSC_i.cxx @@ -42,5 +42,18 @@ Engines_DSC_i(CORBA::ORB_ptr orb, #endif } +Engines_DSC_i:: +Engines_DSC_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif) : Engines_Component_i(orb, poa, container, instanceName, interfaceName) +{ +#ifdef _DEBUG_ + std::cerr << "--Engines_DSC_i: MARK 1 --" << instanceName << "----" << std::endl; +#endif +} + Engines_DSC_i::~Engines_DSC_i() {} diff --git a/src/DSC/DSC_Basic/DSC_i.hxx b/src/DSC/DSC_Basic/DSC_i.hxx index 6a495f9ce..a66be1d56 100644 --- a/src/DSC/DSC_Basic/DSC_i.hxx +++ b/src/DSC/DSC_Basic/DSC_i.hxx @@ -56,6 +56,12 @@ public: const char *instanceName, const char *interfaceName, bool notif = false); + Engines_DSC_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif = false); virtual ~Engines_DSC_i(); diff --git a/src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx b/src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx index 39a8cac49..fde8203a8 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx +++ b/src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx @@ -13,7 +13,7 @@ PySupervCompo::PySupervCompo( CORBA::ORB_ptr orb, const char *instanceName, const char *interfaceName, bool notif) : - Superv_Component_i(orb, poa,poa->reference_to_id(contain), instanceName, interfaceName) + Superv_Component_i(orb, poa,contain, instanceName, interfaceName) { } diff --git a/src/DSC/DSC_User/Superv_Component_i.cxx b/src/DSC/DSC_User/Superv_Component_i.cxx index 3f2a3e972..4a6449990 100644 --- a/src/DSC/DSC_User/Superv_Component_i.cxx +++ b/src/DSC/DSC_User/Superv_Component_i.cxx @@ -50,6 +50,20 @@ Superv_Component_i::Superv_Component_i(CORBA::ORB_ptr orb, register_factory("PALM", new palm_port_factory()); register_factory("CALCIUM", new calcium_port_factory()); } +Superv_Component_i::Superv_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif) : Engines_DSC_i(orb, poa, container, instanceName, interfaceName) +{ +#ifdef _DEBUG_ + std::cerr << "--Superv_Component_i : MARK 1 ---- " << instanceName << "----" << std::endl; +#endif + register_factory("BASIC", new basic_port_factory()); + register_factory("PALM", new palm_port_factory()); + register_factory("CALCIUM", new calcium_port_factory()); +} Superv_Component_i::~Superv_Component_i() diff --git a/src/DSC/DSC_User/Superv_Component_i.hxx b/src/DSC/DSC_User/Superv_Component_i.hxx index 174380f05..2c8467e05 100644 --- a/src/DSC/DSC_User/Superv_Component_i.hxx +++ b/src/DSC/DSC_User/Superv_Component_i.hxx @@ -65,6 +65,12 @@ public: const char *instanceName, const char *interfaceName, bool notif = false); + Superv_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif = false); virtual ~Superv_Component_i(); // Exceptions declarations.