]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
CCAR: add an experimental feature : standalone component CCARexeccompoEnd
authorcaremoli <caremoli>
Sun, 1 Jun 2008 16:50:49 +0000 (16:50 +0000)
committercaremoli <caremoli>
Sun, 1 Jun 2008 16:50:49 +0000 (16:50 +0000)
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

src/Container/Component_i.cxx
src/Container/Container_i.cxx
src/Container/SALOME_Component_i.hxx
src/DSC/DSC_Basic/DSC_i.cxx
src/DSC/DSC_Basic/DSC_i.hxx
src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx
src/DSC/DSC_User/Superv_Component_i.cxx
src/DSC/DSC_User/Superv_Component_i.hxx

index cfeeefc9b10549266744c661ffb5d7af1dae41d4..867411196bac4f20c75227798e473c4533e4217b 100644 (file)
@@ -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);
 }
 
 //=============================================================================
index 41e2b5b61ab952a652a7f01ce896b388e41a39b7..0095b0bc579c69fdc082d273322ff3eb4f4137b0 100644 (file)
@@ -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();
+        }
+    }
 }
 
 //=============================================================================
index 03234c307d2a2a16d397b3d552b86f24a11b5f1d..3d49b89c528a0342ba98a61c92e3f9b0dd7a3d5b 100644 (file)
@@ -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;
index bf67a554cbd382c6e93e4cb6bc57cae2c5999619..2daa87423b6fe1872cfbabe9000de9607aaf3f05 100644 (file)
@@ -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() {}
 
index 6a495f9ce2ab82c9a22afe6ca379a4ebea06f827..a66be1d56e039c1b5df37696b18af74dd40f7c0f 100644 (file)
@@ -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();
 
index 39a8cac490f3ac57edf3170a4747b52891de6379..fde8203a883a32ef91b1556435fce8ae0c7c9f9e 100644 (file)
@@ -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)
 {
 }
 
index 3f2a3e972a17535254fcd1348a66cdc537269938..4a6449990a17011369addfff6c62565a3ef0894c 100644 (file)
@@ -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() 
index 174380f050558a247ac3e5eea60a0586e16f4a61..2c8467e053ff73218682f481155d8a5ae4a06f23 100644 (file)
@@ -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.