]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
PR: container lifecycle, new design, first part
authorprascle <prascle>
Mon, 18 Apr 2005 06:02:43 +0000 (06:02 +0000)
committerprascle <prascle>
Mon, 18 Apr 2005 06:02:43 +0000 (06:02 +0000)
14 files changed:
idl/SALOME_Component.idl
idl/SALOME_ContainerManager.idl
src/Container/Component_i.cxx
src/Container/Container_i.cxx
src/Container/SALOME_Component_i.hxx
src/Container/SALOME_Container_i.hxx
src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx
src/LifeCycleCORBA/SALOME_LifeCycleCORBA.hxx
src/NamingService/NamingService_WaitForServerReadiness.cxx
src/NamingService/SALOME_NamingService.cxx
src/NamingService/SALOME_NamingService.hxx
src/Session/Session_ServerThread.cxx
src/TestContainer/SALOME_TestComponent_i.cxx
src/TestContainer/TestContainer.cxx

index f60922c42005cc289f2c19b486e948863700cfdc..eae1f3d970dd5cee26d15873bdf0a94b4184ded9 100644 (file)
 #ifndef _SALOME_COMPONENT_IDL_
 #define _SALOME_COMPONENT_IDL_
 /*!  
-
-This is a package of interfaces used for connecting new components to %SALOME application. It also contains a set of interfaces used
-for management of %MED component in %SALOME application.
+This is a package of interfaces used for connecting new components to %SALOME
+application. It also contains a set of interfaces used for management of %MED
+component in %SALOME application.
 */
 module Engines
 {
-/*!
+  /*!
     General Key Value Structure to set or get properties, for component
-*/
+  */
   struct KeyValuePair
   {
     string key;
@@ -45,134 +45,221 @@ module Engines
 
   interface Component ;
 
-/*! \brief Interface of the %Container
+  /*! \brief Interface of the %Container
+  This interface defines the process of loading and registration
+  of new components in %SALOME application
+  */
 
-   This interface defines the process of loading and registration
-    of new components in %SALOME application
-*/
   interface Container
   {
 
-/*!
-    Loads into the container a new component, registers it and starts it's CORBA servant.
-    \param nameToRegister     Name of the component which will be registered in Registry (or Name Service)
-    \param componentName     Name of the constructed library of the %component
-    \return a loaded component
-*/
-    Component load_impl(in string nameToRegister, in string componentName);
+    /*!
+      Loads a new component class (dynamic library).
+      \param componentLibraryName like libCOMPONENTEngine.so
+      \return true if load successfull or already done, false otherwise
+    */
+    boolean load_component_Library(in string componentLibraryName);
 
-/*!
-    Loads into the container a new component, registers it and starts it's CORBA servant.
-    \param nameToRegister    Name used to register in Naming Service, the component instance 
-    \param componentName     Name of the %component
-    \return a new instance of the component or the registered component if already registered or Nil if not possible
-*/
-    Component instance(in string nameToRegister, in string componentName);
+    /*!
+      Creates a new servant instance of a component.
+      Component library must be loaded.
+      \param nameToRegister Name of the component which will be registered
+                            in Registry and Name Service,
+                         (instance bumber suffix added to the registered name)
+      \param componentName  Name of the constructed library of the %component
+      \param studyId        0 if instance is not associated to a study, 
+                            >0 otherwise (== study id)
+      \return a loaded component
+    */
+    Component create_component_instance(in string nameToRegister,
+                                       in string componentLibraryName,
+                                       in long studyId);
 
-/*!
-    Stops the component servant, and deletes all related objects
-    \param component_i     Component to be removed
-*/
+    /*!
+      Finds a servant instance of a component
+      \param registeredName  Name of the component in Registry or Name Service,
+                             without instance suffix number
+      \param studyId        0 if instance is not associated to a study, 
+                            >0 otherwise (== study id)
+      \return the first instance found with same studyId
+    */
+    Component find_component_instance(in string registeredName,
+                                     in long studyId);
+
+    /*!
+      Find a servant instance of a component, or create a new one.
+      Loads the component library if needed.
+      Only applicable to multiStudy components.
+      \param nameToRegister    Name of the component which will be registered
+                               in Registry (or Name Service)
+      \param componentName     Name of the constructed library of the %component
+      \return a loaded component
+    */
+    Component load_impl(in string nameToRegister,
+                       in string componentName);
+
+    /*!
+      Stops the component servant, and deletes all related objects
+      \param component_i     Component to be removed
+    */
     void remove_impl(in Component component_i);
 
-/*!
-    Discharges all components from the container.
-*/
+    /*!
+      Discharges all components from the container.
+    */
     void finalize_removal() ;
-/*!
-     Determines whether the server has been loaded or not.
-*/
 
+    /*!
+      Determines whether the server has been loaded or not.
+    */
     void ping();
-/*!
-   Name of the %container
-*/
+
+    /*!
+      Name of the %container
+    */
     readonly attribute string name ;
-/*!
-   Name of the machine containing this container (location of the container).
-*/
-    readonly attribute string machineName ;
-/*!
-   Returns True if the %container has been killed
-*/
-    boolean Kill_impl() ;
-/*!
-   Shutdown the Container process.
-*/
+
+    /*!
+      Shutdown the Container process.
+    */
     oneway void Shutdown();
-/*!
-   Returns the hostname of the container
-*/
+
+    /*!
+      Returns the hostname of the container
+    */
     string getHostName();
-/*!
-   Returns the PID of the container
-*/
+
+    /*!
+      Returns the PID of the container
+    */
     long getPID();
+
+    /*!
+      Returns True if the %container has been killed.
+      Kept for Superv compilation but can't work, unless oneway...
+      TO REMOVE !
+    */
+    boolean Kill_impl() ;
+
+    // -------------------------- removed -------------------------------
+
+    /*!
+      Loads into the container a new component, registers it and starts it's
+      CORBA servant.
+      \param nameToRegister    Name used to register in Naming Service,
+                               the component instance 
+      \param componentName     Name of the %component
+      \return a new instance of the component or the registered component
+               if already registered or Nil if not possible
+    */
+    //    Component instance(in string nameToRegister, in string componentName);
+
+
+    /*!
+      Name of the machine containing this container (location of the container).
+    */
+    //    readonly attribute string machineName ;
+
+
   };
-/*! \brief Interface of the %component
 
-    This interface is used for interaction between the %container and the %component and between
-    the components inside the container.
-*/
+
+
+  /*! \brief Interface of the %component
+  This interface is used for interaction between the %container and the
+  %component and between the components inside the container.
+  */
   interface Component
   {
-/*!
-   The name of the instance of the %Component
-*/
+    /*!
+      The name of the instance of the %Component
+    */
     readonly attribute string instanceName ;
-/*!
-   The name of the interface of the %Component
-*/
+
+    /*!
+      The name of the interface of the %Component
+    */
     readonly attribute string interfaceName ;
-/*!
-    Determines whether the server has already been loaded or not.
-*/
+
+    /*!
+      Determines whether the server has already been loaded or not.
+    */
     void ping();
-/*!
-    Deactivates the %Component.
-*/
+
+//     /*!
+//       Set study associated to component instance
+//       \param studyId
+//       (=0:  multistudy component instance,
+//        >0: study id associated to this instance
+//       \return false if already set with a different value (change not possible)
+//     */
+//     boolean setStudyId(in long studyId);
+
+    /*!
+      get study associated to component instance
+      \return -1: not initialised (Internal Error)
+               0: multistudy component instance
+              >0: study id associated to this instance
+    */
+    long getStudyId();
+
+    /*!
+      Deactivates the %Component.
+    */
     void destroy() ;
-/*!
-    Returns the container that the %Component refers to.
-*/
+
+    /*!
+      Returns the container that the %Component refers to.
+    */
     Container GetContainerRef() ;
-/*!
-    Gives a sequence of (key=string,value=any) to the component. 
-    Base class component stores the sequence in a map.
-    The map is cleared before.
-    This map is for use by derived classes. 
-*/
+
+    /*!
+      Gives a sequence of (key=string,value=any) to the component. 
+      Base class component stores the sequence in a map.
+      The map is cleared before.
+      This map is for use by derived classes. 
+    */
     void setProperties(in FieldsDict dico);
-/*!
-    returns a previously stored map (key=string,value=any) as a sequence.
-    See setProperties(in FieldsDict dico).
-*/
+
+    /*!
+      returns a previously stored map (key=string,value=any) as a sequence.
+      See setProperties(in FieldsDict dico).
+    */
     FieldsDict getProperties();
-/*!
-   This method is used by the %SUPERVISOR component. It sets the names of the graph and of the node.
-   \param aGraphName Name of graph
-   \param aNodeName Name of node
-*/
+
+    /*!
+      This method is used by the %SUPERVISOR component. It sets the names of
+      the graph and of the node.
+      \param aGraphName Name of graph
+      \param aNodeName Name of node
+    */
     void Names( in string aGraphName , in string aNodeName ) ;
-/*!
-   Returns True if the %Component has been killed.
-*/
+
+    /*!
+      Returns True if the %Component has been killed.
+    */
     boolean Kill_impl() ;
-/*!
-   Returns True if the activity of the %Component has been stopped. (It's action can't be resumed)
-*/
+
+    /*!
+      Returns True if the activity of the %Component has been stopped.
+      (It's action can't be resumed)
+    */
     boolean Stop_impl() ;
-/*!
-   Returns True if the activity of the %Component has been suspended. (It's action can be resumed)
-*/
+
+    /*!
+      Returns True if the activity of the %Component has been suspended.
+      (It's action can be resumed)
+    */
     boolean Suspend_impl() ;
-/*!
-   Returns True if the activity of the %Component has been resumed.
-*/
+
+    /*!
+      Returns True if the activity of the %Component has been resumed.
+    */
     boolean Resume_impl() ;
-/*!
-   Returns the Cpu used (long does not run with python !...)
-*/
+
+    /*!
+      Returns the Cpu used (long does not run with python !...)
+    */
     long CpuUsed_impl() ;
   } ;
 } ;
index d8a57247e64dc64a88d089854c57999d41949d2d..9e9ca413a4a9311623dcd546893e2d0e9975fcf9 100644 (file)
@@ -9,7 +9,8 @@ module Engines
 /*!
     Type to describe properties of wanted resource.
 */
-struct MachineParameters {
+struct MachineParameters
+{
   string container_name;
   string hostname;
   string OS;
@@ -29,9 +30,13 @@ struct MachineParameters {
 */
   interface ContainerManager
   {
-    Container FindOrStartContainer( in string containerName, in MachineList possibleComputers);
+    Container FindOrStartContainer( in string containerName,
+                                   in MachineList possibleComputers);
+
     string FindBest(in MachineList possibleComputers);
-    MachineList GetFittingResources( in MachineParameters params, in string componentName );
+
+    MachineList GetFittingResources( in MachineParameters params,
+                                    in string componentName );
     void Shutdown();
     void ShutdownContainers();
   } ;
index ff343a2cc5065e9a6c22413bd13dc2dfca994d59..04eff5a0d25599213588980d420968f58e6da52a 100644 (file)
@@ -26,6 +26,7 @@
 //  Module : SALOME
 //  $Header$
 
+#define private protected
 #include "SALOME_Component_i.hxx"
 #include "SALOME_Container_i.hxx"
 #include "RegistryConnexion.hxx"
 #include <dlfcn.h>
 #include <cstdlib>
 #include "utilities.h"
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
 using namespace std;
 
 extern bool _Sleeping ;
 static Engines_Component_i * theEngines_Component ;
 
+bool Engines_Component_i::_isMultiStudy = true;
+bool Engines_Component_i::_isMultiInstance = false;
+
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 Engines_Component_i::Engines_Component_i()
 {
 //  MESSAGE("Component constructor");
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
                                         PortableServer::POA_ptr poa, 
                                         PortableServer::ObjectId * contId, 
@@ -53,18 +74,33 @@ Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
   _instanceName(instanceName),
   _interfaceName(interfaceName),
   _myConnexionToRegistry(0),
-  _ThreadId(0) , _ThreadCpuUsed(0) , _Executed(false) , _graphName("") , _nodeName("") {
+  _ThreadId(0) ,
+  _ThreadCpuUsed(0) ,
+  _Executed(false) ,
+  _graphName("") ,
+  _nodeName(""),
+ _studyId(-1)
+{
   MESSAGE("Component constructor with instanceName "<< _instanceName);
+  SCRUTE(pd_refCount);
   _orb = CORBA::ORB::_duplicate(orb);
   _poa = PortableServer::POA::_duplicate(poa);
   _contId = contId ;
   CORBA::Object_var o = _poa->id_to_reference(*contId); // container ior...
   const CORBA::String_var ior = _orb->object_to_string(o);
-  _myConnexionToRegistry = new RegistryConnexion(0, 0, ior, "theSession", _instanceName.c_str());
+  _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession",
+                                                _instanceName.c_str());
 
   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
+  SCRUTE(pd_refCount);
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 // Constructeur pour composant parallele: ne pas faire appel au registry!!
 Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
                                         PortableServer::POA_ptr poa, 
@@ -72,44 +108,111 @@ Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb,
                                         const char *instanceName,
                                         const char *interfaceName,
                                         int flag,
-                                         bool notif )
-  : _instanceName(instanceName),
-    _interfaceName(interfaceName),
-    _myConnexionToRegistry(0),
-    _ThreadId(0) , _ThreadCpuUsed(0) , _Executed(false) , _graphName("") , _nodeName("") {
-//  MESSAGE("Component constructor with instanceName "<< _instanceName);
+                                         bool notif ) :
+ _instanceName(instanceName),
+ _interfaceName(interfaceName),
+ _myConnexionToRegistry(0),
+ _ThreadId(0) ,
+ _ThreadCpuUsed(0) ,
+ _Executed(false) ,
+ _graphName("") ,
+ _nodeName(""),
+ _studyId(-1)
+{
+  //  MESSAGE("Component constructor with instanceName "<< _instanceName);
   _orb = CORBA::ORB::_duplicate(orb);
   _poa = PortableServer::POA::_duplicate(poa);
   _contId = contId ;
-  //  CORBA::Object_var myself = this->_this(); //appel a _this = increment reference
 
   _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif);
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 Engines_Component_i::~Engines_Component_i()
 {
   MESSAGE("Component destructor");
-//   delete _myConnexionToRegistry;
-//   _myConnexionToRegistry = 0 ;
 }
 
-char* Engines_Component_i::instanceName() {
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+char* Engines_Component_i::instanceName()
+{
    return CORBA::string_dup(_instanceName.c_str()) ;
 }
 
-char* Engines_Component_i::interfaceName() {
-   return CORBA::string_dup(_interfaceName.c_str()) ;
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+char* Engines_Component_i::interfaceName()
+{
+  return CORBA::string_dup(_interfaceName.c_str()) ;
+}
+
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+CORBA::Boolean Engines_Component_i::setStudyId(CORBA::Long studyId)
+{
+  ASSERT( studyId >= 0);
+  CORBA::Boolean ret = false;
+  if (_studyId < 0)
+    {
+      _studyId = studyId;
+      ret = true;
+    }
+  else
+    if ( _studyId == studyId) ret = true;
+  return ret;
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+CORBA::Long Engines_Component_i::getStudyId()
+{
+  return _studyId;
+}
+
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 void Engines_Component_i::ping()
 {
   MESSAGE("Engines_Component_i::ping() pid "<< getpid() << " threadid "
           << pthread_self());
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 void Engines_Component_i::destroy()
 {
   MESSAGE("Engines_Component_i::destroy()");
+  SCRUTE(pd_refCount);
 
   delete _notifSupplier;
   _notifSupplier = 0;
@@ -119,10 +222,18 @@ void Engines_Component_i::destroy()
   _poa->deactivate_object(*_id) ;
   CORBA::release(_poa) ;
   delete(_id) ;
+  SCRUTE(pd_refCount);
   _thisObj->_remove_ref();
+  SCRUTE(pd_refCount);
   MESSAGE("Engines_Component_i::destroyed") ;
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 Engines::Container_ptr Engines_Component_i::GetContainerRef()
 {
   MESSAGE("Engines_Component_i::GetContainerRef");
@@ -130,12 +241,24 @@ Engines::Container_ptr Engines_Component_i::GetContainerRef()
   return Engines::Container::_narrow(o);
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 PortableServer::ObjectId * Engines_Component_i::getId()
 {
 //  MESSAGE("PortableServer::ObjectId * Engines_Component_i::getId()");
   return _id ;
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 void Engines_Component_i::setProperties(const Engines::FieldsDict& dico)
 {
   _fieldsDict.clear();
@@ -146,6 +269,12 @@ void Engines_Component_i::setProperties(const Engines::FieldsDict& dico)
     }
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 Engines::FieldsDict* Engines_Component_i::getProperties()
 {
   Engines::FieldsDict_var copie = new Engines::FieldsDict;
@@ -161,24 +290,32 @@ Engines::FieldsDict* Engines_Component_i::getProperties()
   return copie._retn();
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 void Engines_Component_i::beginService(const char *serviceName)
 {
-  MESSAGE(pthread_self() << "Send BeginService notification for " << serviceName << endl
-         << "Component instance : " << _instanceName << endl << endl);
+  MESSAGE(pthread_self() << "Send BeginService notification for " <<serviceName
+         << endl << "Component instance : " << _instanceName << endl << endl);
   _ThreadId = pthread_self() ;
   _StartUsed = 0 ;
   _StartUsed = CpuUsed_impl() ;
   _ThreadCpuUsed = 0 ;
   _Executed = true ;
   _serviceName = serviceName ;
-  if ( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS , NULL ) ) {
-    perror("pthread_setcanceltype ") ;
-    exit(0) ;
-  }
-  if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , NULL ) ) {
-    perror("pthread_setcancelstate ") ;
-    exit(0) ;
-  }
+  if ( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS , NULL ) )
+    {
+      perror("pthread_setcanceltype ") ;
+      exit(0) ;
+    }
+  if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , NULL ) )
+    {
+      perror("pthread_setcancelstate ") ;
+      exit(0) ;
+    }
 //  MESSAGE(pthread_self() << " Return from BeginService for " << serviceName
 //          << " ThreadId " << _ThreadId << " StartUsed " << _StartUsed
 //          << " _graphName " << _graphName << " _nodeName " << _nodeName );
@@ -194,7 +331,7 @@ void Engines_Component_i::beginService(const char *serviceName)
        {
          const char* value;
          (*it).second >>= value;
-         // --- todo: replace __GNUC__ test by an autoconf macro AC_CHECK_FUNC...
+         // --- todo: replace __GNUC__ test by an autoconf macro AC_CHECK_FUNC.
 #if defined __GNUC__
          int ret = setenv(cle.c_str(), value, overwrite);
 #else
@@ -202,7 +339,7 @@ void Engines_Component_i::beginService(const char *serviceName)
          std::string s(cle);
          s+='=';
          s+=value;
-         //char* cast because 1st arg of linux putenv function is not a const char* !!!
+         //char* cast because 1st arg of linux putenv function is not a const char* !
          int ret=putenv((char *)s.c_str());
          //End of CCRT porting
 #endif
@@ -211,56 +348,104 @@ void Engines_Component_i::beginService(const char *serviceName)
     }
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 void Engines_Component_i::endService(const char *serviceName)
 {
   _ThreadCpuUsed = CpuUsed_impl() ;
-  MESSAGE(pthread_self() << " Send EndService notification for " << serviceName << endl
-         << " Component instance : " << _instanceName << " StartUsed " << _StartUsed << " _ThreadCpuUsed "
-          << _ThreadCpuUsed << endl << endl);
+  MESSAGE(pthread_self() << " Send EndService notification for " << serviceName
+         << endl << " Component instance : " << _instanceName << " StartUsed "
+          << _StartUsed << " _ThreadCpuUsed "<< _ThreadCpuUsed << endl <<endl);
   _ThreadId = 0 ;
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 void Engines_Component_i::Names( const char * graphName ,
-                                 const char * nodeName ) {
+                                 const char * nodeName )
+{
   _graphName = graphName ;
   _nodeName = nodeName ;
-//  MESSAGE("Engines_Component_i::Names( '" << _graphName << "' , '"
-//          << _nodeName << "' )");
+  //  MESSAGE("Engines_Component_i::Names( '" << _graphName << "' , '"
+  //          << _nodeName << "' )");
 }
 
-char* Engines_Component_i::graphName() {
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+char* Engines_Component_i::graphName()
+{
   return CORBA::string_dup( _graphName.c_str() ) ;
 }
 
-char* Engines_Component_i::nodeName() {
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+char* Engines_Component_i::nodeName()
+{
   return CORBA::string_dup( _nodeName.c_str() ) ;
 }
 
-bool Engines_Component_i::Killer( pthread_t ThreadId , int signum ) {
-  if ( ThreadId ) {
-    if ( signum == 0 ) {
-      if ( pthread_cancel( ThreadId ) ) {
-        perror("Killer pthread_cancel error") ;
-        return false ;
-      }
-      else {
-        MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId << " pthread_canceled") ;
-      }
-    }
-    else {
-      if ( pthread_kill( ThreadId , signum ) == -1 ) {
-        perror("Killer pthread_kill error") ;
-        return false ;
-      }
-      else {
-        MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId << " pthread_killed("
-                << signum << ")") ;
-      }
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+bool Engines_Component_i::Killer( pthread_t ThreadId , int signum )
+{
+  if ( ThreadId )
+    {
+      if ( signum == 0 )
+       {
+         if ( pthread_cancel( ThreadId ) )
+           {
+             perror("Killer pthread_cancel error") ;
+             return false ;
+           }
+         else
+           {
+             MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId
+                     << " pthread_canceled") ;
+           }
+       }
+      else
+       {
+         if ( pthread_kill( ThreadId , signum ) == -1 )
+           {
+             perror("Killer pthread_kill error") ;
+             return false ;
+           }
+         else 
+           {
+             MESSAGE(pthread_self() << "Killer : ThreadId " << ThreadId
+                     << " pthread_killed(" << signum << ")") ;
+           }
+       }
     }
-  }
   return true ;
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 bool Engines_Component_i::Kill_impl() {
 //  MESSAGE("Engines_Component_i::Kill_i() pthread_t "<< pthread_self()
 //          << " pid " << getpid() << " instanceName "
@@ -276,129 +461,209 @@ bool Engines_Component_i::Kill_impl() {
   return RetVal ;
 }
 
-bool Engines_Component_i::Stop_impl() {
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+bool Engines_Component_i::Stop_impl()
+{
   MESSAGE("Engines_Component_i::Stop_i() pthread_t "<< pthread_self()
           << " pid " << getpid() << " instanceName "
           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
           << dec << " _ThreadId " << _ThreadId );
+  
   bool RetVal = false ;
-  if ( _ThreadId > 0 && pthread_self() != _ThreadId ) {
-    RetVal = Killer( _ThreadId , 0 ) ;
-    _ThreadId = (pthread_t ) -1 ;
-  }
+  if ( _ThreadId > 0 && pthread_self() != _ThreadId )
+    {
+      RetVal = Killer( _ThreadId , 0 ) ;
+      _ThreadId = (pthread_t ) -1 ;
+    }
   return RetVal ;
 }
 
-bool Engines_Component_i::Suspend_impl() {
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+bool Engines_Component_i::Suspend_impl()
+{
   MESSAGE("Engines_Component_i::Suspend_i() pthread_t "<< pthread_self()
           << " pid " << getpid() << " instanceName "
           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
           << dec << " _ThreadId " << _ThreadId );
   bool RetVal = false ;
-  if ( _ThreadId > 0 && pthread_self() != _ThreadId ) {
-    if ( _Sleeping ) {
-      return false ;
-    }
-    else {
-      RetVal = Killer( _ThreadId ,SIGINT ) ;
+  if ( _ThreadId > 0 && pthread_self() != _ThreadId )
+    {
+      if ( _Sleeping )
+       {
+         return false ;
+       }
+    else 
+      {
+       RetVal = Killer( _ThreadId ,SIGINT ) ;
+      }
     }
-  }
   return RetVal ;
 }
 
-bool Engines_Component_i::Resume_impl() {
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+bool Engines_Component_i::Resume_impl()
+{
   MESSAGE("Engines_Component_i::Resume_i() pthread_t "<< pthread_self()
           << " pid " << getpid() << " instanceName "
           << _instanceName.c_str() << " interface " << _interfaceName.c_str()
           << " machineName " << GetHostname().c_str()<< " _id " << hex << _id
           << dec << " _ThreadId " << _ThreadId );
   bool RetVal = false ;
-  if ( _ThreadId > 0 && pthread_self() != _ThreadId ) {
-    if ( _Sleeping ) {
-      _Sleeping = false ;
-      RetVal = true ;
-    }
-    else {
-      RetVal = false ;
+  if ( _ThreadId > 0 && pthread_self() != _ThreadId )
+    {
+    if ( _Sleeping ) 
+      {
+       _Sleeping = false ;
+       RetVal = true ;
+      }
+    else
+      {
+       RetVal = false ;
+      }
     }
-  }
   return RetVal ;
 
 }
 
-void SetCpuUsed() {
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+void SetCpuUsed()
+{
   theEngines_Component->SetCurCpu() ;
 }
-void Engines_Component_i::SetCurCpu() {
+
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+void Engines_Component_i::SetCurCpu()
+{
   _ThreadCpuUsed =  CpuUsed() ;
-//  MESSAGE(pthread_self() << " Engines_Component_i::SetCurCpu() _ThreadCpuUsed " << _ThreadCpuUsed) ;
+  //  MESSAGE(pthread_self() << 
+  //  " Engines_Component_i::SetCurCpu() _ThreadCpuUsed " << _ThreadCpuUsed) ;
 }
 
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <unistd.h>
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
 
-long Engines_Component_i::CpuUsed() {
+long Engines_Component_i::CpuUsed()
+{
   long cpu = 0 ;
   struct rusage usage ;
-  if ( _ThreadId || _Executed ) {
-    if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
-      perror("Engines_Component_i::CpuUsed") ;
-      return 0 ;
+  if ( _ThreadId || _Executed )
+    {
+      if ( getrusage( RUSAGE_SELF , &usage ) == -1 )
+       {
+         perror("Engines_Component_i::CpuUsed") ;
+         return 0 ;
+       }
+      cpu = usage.ru_utime.tv_sec - _StartUsed ;
+      // cout << pthread_self() << " Engines_Component_i::CpuUsed " << " "
+      //      << _serviceName   << usage.ru_utime.tv_sec << " - " << _StartUsed
+      //      << " = " << cpu << endl ;
+    }
+  else
+    {
+      // cout << pthread_self() << "Engines_Component_i::CpuUsed _ThreadId "
+      //      << _ThreadId << " " << _serviceName<< " _StartUsed " 
+      //      << _StartUsed << endl ;
     }
-    cpu = usage.ru_utime.tv_sec - _StartUsed ;
-//    cout << pthread_self() << " Engines_Component_i::CpuUsed " << " " << _serviceName
-//         << usage.ru_utime.tv_sec << " - " << _StartUsed << " = " << cpu << endl ;
-  }
-  else {
-//    cout << pthread_self() << "Engines_Component_i::CpuUsed _ThreadId " << _ThreadId << " " << _serviceName
-//         << " _StartUsed " << _StartUsed << endl ;
-  }
   return cpu ;
 }
 
-CORBA::Long Engines_Component_i::CpuUsed_impl() {
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+CORBA::Long Engines_Component_i::CpuUsed_impl()
+{
   long cpu = 0 ;
-  if ( _ThreadId || _Executed ) {
-    if ( _ThreadId > 0 ) {
-      if ( pthread_self() != _ThreadId ) {
-        if ( _Sleeping ) {
-        }
-        else {
-// Get Cpu in the appropriate thread with that object !...
-          theEngines_Component = this ;
-          Killer( _ThreadId ,SIGUSR1 ) ;
-        }
+  if ( _ThreadId || _Executed )
+    {
+    if ( _ThreadId > 0 )
+      {
+      if ( pthread_self() != _ThreadId )
+       {
+        if ( _Sleeping )
+         {
+         }
+        else
+         {
+           // Get Cpu in the appropriate thread with that object !...
+           theEngines_Component = this ;
+           Killer( _ThreadId ,SIGUSR1 ) ;
+         }
         cpu = _ThreadCpuUsed ;
+       }
+      else
+       {
+         _ThreadCpuUsed = CpuUsed() ;
+         cpu = _ThreadCpuUsed ;
+         // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
+         //      << _serviceName << " " << cpu << endl ;
       }
-      else {
-        _ThreadCpuUsed = CpuUsed() ;
-        cpu = _ThreadCpuUsed ;
-//        cout << pthread_self() << " Engines_Component_i::CpuUsed_impl " << _serviceName << " " << cpu
-//             << endl ;
+    }
+    else 
+      {
+       cpu = _ThreadCpuUsed ;
+       // cout << pthread_self() << " Engines_Component_i::CpuUsed_impl "
+       //      << _serviceName << " " << cpu<< endl ;
       }
     }
-    else {
-      cpu = _ThreadCpuUsed ;
-//      cout << pthread_self() << " Engines_Component_i::CpuUsed_impl " << _serviceName << " " << cpu
-//           << endl ;
+  else
+    {
+      // cout << pthread_self()<<"Engines_Component_i::CpuUsed_impl _ThreadId "
+      //      <<_ThreadId <<" "<<_serviceName<<" _StartUsed "<<_StartUsed<<endl;
     }
-  }
-  else {
-//    cout << pthread_self() << "Engines_Component_i::CpuUsed_impl _ThreadId " << _ThreadId << " "
-//         << _serviceName << " _StartUsed " << _StartUsed << endl ;
-  }
   return cpu ;
 }
 
-// Send message to event channel
+//=============================================================================
+/*! 
+ *  Send message to event channel
+ */
+//=============================================================================
 
-void Engines_Component_i::sendMessage(const char *event_type, const char *message) {
+void Engines_Component_i::sendMessage(const char *event_type,
+                                     const char *message)
+{
     _notifSupplier->Send(graphName(), nodeName(), event_type, message);
 }
 
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
 string Engines_Component_i::GetDynLibraryName(const char *componentName)
 {
   string ret="lib";
@@ -407,7 +672,15 @@ string Engines_Component_i::GetDynLibraryName(const char *componentName)
   return ret;
 }
 
-string Engines_Component_i::BuildComponentNameForNS(const char *ComponentName, const char *ContainerName, const char *hostname)
+//=============================================================================
+/*! 
+ *
+ */
+//=============================================================================
+
+string Engines_Component_i::BuildComponentNameForNS(const char *ComponentName,
+                                                   const char *ContainerName,
+                                                   const char *hostname)
 {
   string ret=Engines_Container_i::BuildContainerNameForNS(ContainerName,hostname);
   ret+="/";
index 2a4257217fc0f766672fc8be8a8c7a98637aea0c..c8528d97950dae3fda406d8da0c6e6f907875bbd 100644 (file)
 //  Module : SALOME
 //  $Header$
 
+#define private public
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SALOME_Component)
 #include "SALOME_Container_i.hxx"
+#include "SALOME_Component_i.hxx"
 #include "SALOME_NamingService.hxx"
-//#include "Utils_SINGLETON.hxx"
 #include "OpUtil.hxx"
 #include <string.h>
 #include <stdio.h>
@@ -55,11 +56,23 @@ extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; }
 
 const char *Engines_Container_i::_defaultContainerName="FactoryServer";
 
+//=============================================================================
+/*! 
+ *  Default constructor, not for use
+ */
+//=============================================================================
+
 Engines_Container_i::Engines_Container_i () :
- _numInstance(0)
 _numInstance(0)
 {
 }
 
+//=============================================================================
+/*! 
+ *  Construtor to use
+ */
+//=============================================================================
+
 Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb, 
                                          PortableServer::POA_ptr poa,
                                          char *containerName ,
@@ -80,71 +93,119 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
   _argc = argc ;
   _argv = argv ;
   int i = strlen( _argv[ 0 ] ) - 1 ;
-  while ( i >= 0 ) {
-    if ( _argv[ 0 ][ i ] == '/' ) {
-      _argv[ 0 ][ i+1 ] = '\0' ;
-      break ;
+  while ( i >= 0 )
+    {
+      if ( _argv[ 0 ][ i ] == '/' )
+       {
+         _argv[ 0 ][ i+1 ] = '\0' ;
+         break ;
+       }
+      i -= 1 ;
     }
-    i -= 1 ;
-  }
   string hostname = GetHostname();
   MESSAGE(hostname << " " << getpid() << " Engines_Container_i starting argc "
          << _argc << " Thread " << pthread_self() ) ;
   i = 0 ;
-  while ( _argv[ i ] ) {
-    MESSAGE("           argv" << i << " " << _argv[ i ]) ;
-    i++ ;
-  }
-  if ( argc != 4 ) {
-    MESSAGE("SALOME_Container usage : SALOME_Container ServerName -ORBInitRef NameService=corbaname::hostname:tcpipPortNumber") ;
-//    exit(0) ;
-  }
-
-  SCRUTE(hostname);
+  while ( _argv[ i ] )
+    {
+      MESSAGE("           argv" << i << " " << _argv[ i ]) ;
+      i++ ;
+    }
+  if ( argc != 4 )
+    {
+      MESSAGE("SALOME_Container usage : SALOME_Container ServerName " <<
+             "-ORBInitRef NameService=corbaname::hostname:tcpipPortNumber") ;
+      //    exit(0) ;
+    }
 
   _containerName = BuildContainerNameForNS(containerName,hostname.c_str());
-
+  
   _orb = CORBA::ORB::_duplicate(orb) ;
   _poa = PortableServer::POA::_duplicate(poa) ;
+  
+  // Pour les containers paralleles: il ne faut pas enregistrer et activer
+  // le container generique, mais le container specialise
 
-  // Pour les containers paralleles: il ne faut pas enregistrer et activer le container generique, mais le container specialise
-  if(activAndRegist){
-    _id = _poa->activate_object(this);
-    _NS = new SALOME_NamingService();//SINGLETON_<SALOME_NamingService>::Instance() ;
-    //ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
-    _NS->init_orb( CORBA::ORB::_duplicate(_orb) ) ;
-    CORBA::Object_var obj=_poa->id_to_reference(*_id);
-    Engines::Container_var pCont 
-      = Engines::Container::_narrow(obj);
-    SCRUTE(_containerName);
-    _NS->Register(pCont, _containerName.c_str()); 
-  }
+  if(activAndRegist)
+    {
+      _id = _poa->activate_object(this);
+      _NS = new SALOME_NamingService();
+      _NS->init_orb( CORBA::ORB::_duplicate(_orb) ) ;
+      CORBA::Object_var obj=_poa->id_to_reference(*_id);
+      Engines::Container_var pCont 
+       = Engines::Container::_narrow(obj);
+      SCRUTE(_containerName);
+      _NS->Register(pCont, _containerName.c_str()); 
+    }
 }
 
+//=============================================================================
+/*! 
+ *  Destructor
+ */
+//=============================================================================
+
 Engines_Container_i::~Engines_Container_i()
 {
   MESSAGE("Container_i::~Container_i()");
   delete _id;
 }
 
+//=============================================================================
+/*! 
+ *  CORBA attribute: Container name (see constructor)
+ */
+//=============================================================================
+
 char* Engines_Container_i::name()
 {
    return CORBA::string_dup(_containerName.c_str()) ;
 }
 
-char* Engines_Container_i::machineName()
+//=============================================================================
+/*! 
+ *  CORBA method: Get the hostName of the Container (without domain extensions)
+ */
+//=============================================================================
+
+char* Engines_Container_i::getHostName()
 {
   string s = GetHostname();
-  MESSAGE("Engines_Container_i::machineName " << s);
-   return CORBA::string_dup(s.c_str()) ;
+  MESSAGE("Engines_Container_i::getHostName " << s);
+  return CORBA::string_dup(s.c_str()) ;
 }
 
+//=============================================================================
+/*! 
+ *  CORBA method: Get the PID (process identification) of the Container
+ */
+//=============================================================================
+
+CORBA::Long Engines_Container_i::getPID()
+{
+  return (CORBA::Long)getpid();
+}
+
+//=============================================================================
+/*! 
+ *  CORBA method: check if servant is still alive
+ */
+//=============================================================================
+
 void Engines_Container_i::ping()
 {
   MESSAGE("Engines_Container_i::ping() pid "<< getpid());
 }
 
-// shutdown corba server
+//=============================================================================
+/*! 
+ *  CORBA method, oneway: Server shutdown. 
+ *  - Container name removed from naming service,
+ *  - servant deactivation,
+ *  - orb shutdown if no other servants in the process 
+ */
+//=============================================================================
+
 void Engines_Container_i::Shutdown()
 {
   MESSAGE("Engines_Container_i::Shutdown()");
@@ -155,138 +216,414 @@ void Engines_Container_i::Shutdown()
     _orb->shutdown(0);
 }
 
-//! Kill current container
-bool Engines_Container_i::Kill_impl() {
-  MESSAGE("Engines_Container_i::Kill() pid "<< getpid() << " containerName "
-          << _containerName.c_str() << " machineName "
-          << GetHostname().c_str());
-  exit( 0 ) ;
-}
 
-Engines::Component_ptr Engines_Container_i::load_impl( const char* nameToRegister,
-                                                      const char* componentName ) {
-
-  _numInstanceMutex.lock() ; // lock on the instance number
-  BEGIN_OF( "Container_i::load_impl " << componentName ) ;
-  _numInstance++ ;
-  char _aNumI[12];
-  sprintf( _aNumI , "%d" , _numInstance ) ;
+//=============================================================================
+/*! 
+ *  CORBA method: load a new component class (dynamic library)
+ *  \param componentLibraryName like "libCOMPONENTEngine.so"
+ *  \return true if dlopen successfull or already done, false otherwise
+ */
+//=============================================================================
 
-  string _impl_name = componentName;
-  string _nameToRegister = nameToRegister;
-  string instanceName = _nameToRegister + "_inst_" + _aNumI ;
-  //SCRUTE(instanceName);
+bool
+Engines_Container_i::load_component_Library(const char* componentLibraryName)
+{
+  string impl_name = componentLibraryName;
+  SCRUTE(impl_name);
 
-  //string absolute_impl_name = _library_path + "lib" + _impl_name + ".so";
-  string absolute_impl_name( _impl_name ) ;
-  SCRUTE(absolute_impl_name);
+  if (_library_map[impl_name])
+    {
+      MESSAGE("Library " << impl_name << " already loaded");
+      return true;
+    }
   void* handle;
-  handle = dlopen( absolute_impl_name.c_str() , RTLD_LAZY ) ;
-  if ( !handle ) {
-    INFOS("Can't load shared library : " << absolute_impl_name);
-    INFOS("error dlopen: " << dlerror());
-    _numInstanceMutex.unlock() ;
-    return Engines::Component::_nil() ;
-  }
-  
-  string factory_name = _nameToRegister + string("Engine_factory");
-  //  SCRUTE(factory_name) ;
+  handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ;
+  if ( !handle )
+    {
+      INFOS("Can't load shared library : " << impl_name);
+      INFOS("error dlopen: " << dlerror());
+      return false;
+    }
+  else
+    {
+      _library_map[impl_name] = handle;
+      return true;
+    }
+}
 
-  typedef  PortableServer::ObjectId * (*FACTORY_FUNCTION)
-                            (CORBA::ORB_ptr,
-                            PortableServer::POA_ptr, 
-                            PortableServer::ObjectId *, 
-                            const char *, 
-                            const char *) ; 
-  FACTORY_FUNCTION Component_factory = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
+//=============================================================================
+/*! 
+ *  CORBA method: Creates a new servant instance of a component.
+ *  The servant registers itself to naming service and Registry.
+ *  \param genericRegisterName  Name of the component instance to register
+ *                         in Registry & Name Service (without _inst_n suffix)
+ *  \param componentName   Name of the constructed library of the component
+ *  \param studyId         0 for multiStudy instance, 
+ *                         study Id (>0) otherwise
+ *  \return a loaded component
+ */
+//=============================================================================
 
-  char *error ;
-  if ( (error = dlerror() ) != NULL) {
-      INFOS("Can't resolve symbol: " + factory_name);
-      SCRUTE(error);
-      _numInstanceMutex.unlock() ;
+Engines::Component_ptr
+Engines_Container_i::create_component_instance(const char*genericRegisterName,
+                                              const char*componentLibraryName,
+                                              CORBA::Long studyId)
+{
+  if (studyId < 0)
+    {
+      INFOS("studyId must be > 0 for mono study instance, =0 for multiStudy");
       return Engines::Component::_nil() ;
     }
 
-  string component_registerName = _containerName + "/" + _nameToRegister;
-  Engines::Component_var iobject = Engines::Component::_nil() ;
-  try {
-    CORBA::Object_var obj = _NS->Resolve( component_registerName.c_str() ) ;
-    if ( CORBA::is_nil( obj ) ) {
-// Instanciate required CORBA object
-      PortableServer::ObjectId * id ;
-      id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str() ,
-                                 _nameToRegister.c_str() ) ;
-  // get reference from id
-      obj = _poa->id_to_reference(*id);
-      iobject = Engines::Component::_narrow( obj ) ;
-
-//  _numInstanceMutex.lock() ; // lock on the add on handle_map (necessary ?)
-  // register the engine under the name containerName.dir/nameToRegister.object
-      _NS->Register( iobject , component_registerName.c_str() ) ;
-      MESSAGE( "Container_i::load_impl " << component_registerName.c_str() << " bound" ) ;
+  string impl_name = componentLibraryName;
+  void* handle = _library_map[impl_name];
+  if ( !handle )
+    {
+      INFOS("shared library " << impl_name <<"must be loaded before instance");
+      return Engines::Component::_nil() ;
     }
-    else { // JR : No ReBind !!!
-      MESSAGE( "Container_i::load_impl " << component_registerName.c_str() << " already bound" ) ;
-      iobject = Engines::Component::_narrow( obj ) ;
+  else
+    {
+      Engines::Component_var iobject = Engines::Component::_nil() ;
+      iobject = createInstance(genericRegisterName,
+                              handle,
+                              studyId);
+      return iobject._retn();
     }
-  }
-  catch (...) {
-    INFOS( "Container_i::load_impl catched" ) ;
-  }
+}
 
-//Jr  _numInstanceMutex.lock() ; // lock on the add on handle_map (necessary ?)
-  handle_map[instanceName] = handle;
-  END_OF("Container_i::load_impl");
-  _numInstanceMutex.unlock() ;
-  return Engines::Component::_duplicate(iobject);
+//=============================================================================
+/*! 
+ *  CORBA method: Finds a servant instance of a component
+ *  \param registeredName  Name of the component in Registry or Name Service,
+ *                         without instance suffix number
+ *  \param studyId         0 if instance is not associated to a study, 
+ *                         >0 otherwise (== study id)
+ *  \return the first instance found with same studyId
+ */
+//=============================================================================
+
+Engines::Component_ptr
+Engines_Container_i::find_component_instance( const char* registeredName,
+                                             CORBA::Long studyId)
+{
+  ASSERT(0);
+}
+
+//=============================================================================
+/*! 
+ *  CORBA method: find or create an instance of the component (servant),
+ *  load a new component class (dynamic library) if required,
+ *  ---- FOR COMPATIBILITY WITH 2.2 ---- 
+ *  ---- USE ONLY FOR MULTISTUDY INSTANCES ! --------
+ *  The servant registers itself to naming service and Registry.
+ *  \param genericRegisterName  Name of the component to register
+ *                              in Registry & Name Service
+ *  \param componentName       Name of the constructed library of the component
+ *  \return a loaded component
+ */
+//=============================================================================
+
+Engines::Component_ptr
+Engines_Container_i::load_impl( const char* genericRegisterName,
+                               const char* componentName )
+{
+  Engines::Component_var iobject = Engines::Component::_nil() ;
+  if (load_component_Library(componentName))
+    iobject = find_or_create_instance(genericRegisterName, componentName);
+  return iobject._retn();
 }
+    
+
+//=============================================================================
+/*! 
+ *  CORBA method: Stops the component servant, and deletes all related objects
+ *  \param component_i     Component to be removed
+ */
+//=============================================================================
 
 void Engines_Container_i::remove_impl(Engines::Component_ptr component_i)
 {
   ASSERT(! CORBA::is_nil(component_i));
   string instanceName = component_i->instanceName() ;
   MESSAGE("unload component " << instanceName);
+  _listInstances_map.erase(instanceName);
   component_i->destroy() ;
-  MESSAGE("test key handle_map");
-  _numInstanceMutex.lock() ; // lock on the remove on handle_map
-  if (handle_map[instanceName]) // if key does not exist, created & initialized null
-    {
-      remove_map[instanceName] = handle_map[instanceName] ;
-    }
-  else MESSAGE("pas d'entree handle_map");
-  handle_map.erase(instanceName) ;   
-  _numInstanceMutex.unlock() ;
-  MESSAGE("contenu handle_map");
-  map<string, void *>::iterator im ;
-  for (im = handle_map.begin() ; im != handle_map.end() ; im ++)
-    {
-      MESSAGE("reste " << (*im).first);
-    }
 }
 
+//=============================================================================
+/*! 
+ *  CORBA method: Discharges all components from the container.
+ */
+//=============================================================================
+
 void Engines_Container_i::finalize_removal()
 {
   MESSAGE("finalize unload : dlclose");
   map<string, void *>::iterator im ;
-  _numInstanceMutex.lock() ; // lock on the explore remove_map & dlclose
-  for (im = remove_map.begin() ; im != remove_map.end() ; im ++)
+  _numInstanceMutex.lock() ; // lock on the explore _remove_map & dlclose
+  for (im = _remove_map.begin() ; im != _remove_map.end() ; im ++)
     {
       void * handle = (*im).second ;
       dlclose(handle) ;
       MESSAGE("dlclose " << (*im).first);
     }
-  remove_map.clear() ;  
+  _remove_map.clear() ;  
   _numInstanceMutex.unlock() ;
-  MESSAGE("remove_map.clear()");
+  MESSAGE("_remove_map.clear()");
+}
+
+//=============================================================================
+/*! 
+ *  CORBA method: Kill the container process with exit(0).
+ *  To remove :  never returns !
+ */
+//=============================================================================
+
+bool Engines_Container_i::Kill_impl()
+{
+  MESSAGE("Engines_Container_i::Kill() pid "<< getpid() << " containerName "
+          << _containerName.c_str() << " machineName "
+          << GetHostname().c_str());
+  INFOS("===============================================================");
+  INFOS("= REMOVE calls to Kill_impl in C++ container                  =");
+  INFOS("===============================================================");
+  //exit( 0 ) ;
+  ASSERT(0);
+}
+
+//=============================================================================
+/*! 
+ *  C++ method: Finds an already existing servant instance of a component, or
+ *              create an instance.
+ *  ---- USE ONLY FOR MULTISTUDY INSTANCES ! --------
+ *  \param genericRegisterName    Name of the component instance to register
+ *                                in Registry & Name Service,
+ *                                (without _inst_n suffix, like "COMPONENT")
+ *  \param componentLibraryName   like "libCOMPONENTEngine.so"
+ *  \return a loaded component
+ * 
+ *  example with names:
+ *  aGenRegisterName = COMPONENT (= first argument)
+ *  impl_name = libCOMPONENTEngine.so (= second argument)
+ *  _containerName = /Containers/cli76ce/FactoryServer
+ *  factoryName = COMPONENTEngine_factory
+ *  component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
+ *
+ *  instanceName = COMPONENT_inst_1
+ *  component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
+ */
+//=============================================================================
+
+Engines::Component_ptr
+Engines_Container_i::find_or_create_instance(string genericRegisterName,
+                                            string componentLibraryName)
+{
+  string aGenRegisterName = genericRegisterName;
+  string impl_name = componentLibraryName;
+  void* handle = _library_map[impl_name];
+  if ( !handle )
+    {
+      INFOS("shared library " << impl_name <<"must be loaded before instance");
+      return Engines::Component::_nil() ;
+    }
+  else
+    {
+      // --- find a registered instance in naming service, or create
+
+      string component_registerBase =
+       _containerName + "/" + aGenRegisterName;
+      Engines::Component_var iobject = Engines::Component::_nil() ;
+      try
+       {
+         CORBA::Object_var obj =
+           _NS->ResolveFirst( component_registerBase.c_str());
+         if ( CORBA::is_nil( obj ) )
+           {
+             iobject = createInstance(genericRegisterName,
+                                      handle,
+                                      0); // force multiStudy instance here !
+           }
+         else
+           { 
+             iobject = Engines::Component::_narrow( obj ) ;
+             Engines_Component_i *servant =
+               dynamic_cast<Engines_Component_i*>
+               (_poa->reference_to_servant(iobject));
+             ASSERT(servant)
+             int studyId = servant->getStudyId(); 
+             ASSERT (studyId >= 0);
+             if (studyId == 0) // multiStudy instance, OK
+               {
+                 // No ReBind !
+                 MESSAGE(component_registerBase.c_str()<<" already bound");
+               }
+             else // monoStudy instance: NOK
+               {
+                 iobject = Engines::Component::_nil();
+                 INFOS("load_impl & find_component_instance methods "
+                       << "NOT SUITABLE for mono study components");
+               }
+           }
+       }
+      catch (...)
+       {
+         INFOS( "Container_i::load_impl catched" ) ;
+       }
+      return iobject._retn();
+    }
 }
 
-void ActSigIntHandler() {
+//=============================================================================
+/*! 
+ *  C++ method: create a servant instance of a component.
+ *  \param genericRegisterName    Name of the component instance to register
+ *                                in Registry & Name Service,
+ *                                (without _inst_n suffix, like "COMPONENT")
+ *  \param handle                 loaded library handle
+ *  \param studyId                0 for multiStudy instance, 
+ *                                study Id (>0) otherwise
+ *  \return a loaded component
+ * 
+ *  example with names:
+ *  aGenRegisterName = COMPONENT (= first argument)
+ *  _containerName = /Containers/cli76ce/FactoryServer
+ *  factoryName = COMPONENTEngine_factory
+ *  component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
+ *  instanceName = COMPONENT_inst_1
+ *  component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
+ */
+//=============================================================================
+
+Engines::Component_ptr
+Engines_Container_i::createInstance(string genericRegisterName,
+                                   void *handle,
+                                   int studyId)
+{
+  // --- find the factory
+
+  string aGenRegisterName = genericRegisterName;
+  string factory_name = aGenRegisterName + string("Engine_factory");
+  SCRUTE(factory_name) ;
+
+  typedef  PortableServer::ObjectId * (*FACTORY_FUNCTION)
+    (CORBA::ORB_ptr,
+     PortableServer::POA_ptr, 
+     PortableServer::ObjectId *, 
+     const char *, 
+     const char *) ;
+
+  FACTORY_FUNCTION Component_factory
+    = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
+
+  char *error ;
+  if ( (error = dlerror() ) != NULL)
+    {
+      INFOS("Can't resolve symbol: " + factory_name);
+      SCRUTE(error);
+      return Engines::Component::_nil() ;
+    }
+
+  // --- create instance
+
+  Engines::Component_var iobject = Engines::Component::_nil() ;
+
+  try
+    {
+      _numInstanceMutex.lock() ; // lock on the instance number
+      _numInstance++ ;
+      int numInstance = _numInstance ;
+      _numInstanceMutex.unlock() ;
+
+      char aNumI[12];
+      sprintf( aNumI , "%d" , numInstance ) ;
+      string instanceName = aGenRegisterName + "_inst_" + aNumI ;
+      string component_registerName =
+       _containerName + "/" + instanceName;
+
+      // --- Instanciate required CORBA object
+
+      PortableServer::ObjectId * id ;
+      id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str(),
+                                aGenRegisterName.c_str() ) ;
+
+      // --- get reference & servant from id
+
+      CORBA::Object_var obj = _poa->id_to_reference(*id);
+      iobject = Engines::Component::_narrow( obj ) ;
+
+      Engines_Component_i *servant =
+       dynamic_cast<Engines_Component_i*>(_poa->reference_to_servant(iobject));
+      ASSERT(servant);
+      SCRUTE(servant->pd_refCount);
+      servant->_remove_ref(); // compensate previous id_to_reference 
+      SCRUTE(servant->pd_refCount);
+      _listInstances_map[instanceName] = iobject;
+      SCRUTE(servant->pd_refCount);
+      ASSERT(servant->setStudyId(studyId));
+
+      // --- register the engine under the name
+      //     containerName(.dir)/instanceName(.object)
+
+      _NS->Register( iobject , component_registerName.c_str() ) ;
+      MESSAGE( component_registerName.c_str() << " bound" ) ;
+    }
+  catch (...)
+    {
+      INFOS( "Container_i::createInstance exception catched" ) ;
+    }
+  return iobject._retn();
+}
+
+
+//=============================================================================
+/*! 
+ *  Retrieves only with container naming convention if it is a python container
+ */
+//=============================================================================
+
+bool Engines_Container_i::isPythonContainer(const char* ContainerName)
+{
+  bool ret=false;
+  int len=strlen(ContainerName);
+  if(len>=2)
+    if(strcmp(ContainerName+len-2,"Py")==0)
+      ret=true;
+  return ret;
+}
+
+//=============================================================================
+/*! 
+ *  Returns string = container path + name, to use in Naming service
+ */
+//=============================================================================
+
+string Engines_Container_i::BuildContainerNameForNS(const char *ContainerName,
+                                                   const char *hostname)
+{
+  string ret="/Containers/";
+  ret += hostname;
+  ret+="/";
+  if (strlen(ContainerName)== 0)
+    ret+=_defaultContainerName;
+  else
+    ret += ContainerName;
+  return ret;
+}
+
+//=============================================================================
+/*! 
+ *  
+ */
+//=============================================================================
+
+void ActSigIntHandler()
+{
   struct sigaction SigIntAct ;
   SigIntAct.sa_sigaction = &SigIntHandler ;
   SigIntAct.sa_flags = SA_SIGINFO ;
-// DEBUG 03.02.2005 : the first parameter of sigaction is not a mask of signals (SIGINT | SIGUSR1) :
-// it must be only one signal ===> one call for SIGINT and an other one for SIGUSR1
+  // DEBUG 03.02.2005 : the first parameter of sigaction is not a mask of signals (SIGINT | SIGUSR1) :
+  // it must be only one signal ===> one call for SIGINT and an other one for SIGUSR1
   if ( sigaction( SIGINT , &SigIntAct, NULL ) ) {
     perror("SALOME_Container main ") ;
     exit(0) ;
@@ -301,7 +638,8 @@ void ActSigIntHandler() {
 void SetCpuUsed() ;
 
 void SigIntHandler(int what , siginfo_t * siginfo ,
-                                        void * toto ) {
+                                        void * toto )
+{
   MESSAGE(pthread_self() << "SigIntHandler what     " << what << endl
           << "              si_signo " << siginfo->si_signo << endl
           << "              si_code  " << siginfo->si_code << endl
@@ -330,120 +668,107 @@ void SigIntHandler(int what , siginfo_t * siginfo ,
   }
 }
 
-// Get the PID of the Container
-
-CORBA::Long Engines_Container_i::getPID() {
-    return (CORBA::Long)getpid();
-}
-
-// Get the hostName of the Container
-
-char* Engines_Container_i::getHostName() {
-    return((char*)(GetHostname().c_str()));
-}
-
-// Retrieves only with container naming convention if it is a python container
-bool Engines_Container_i::isPythonContainer(const char* ContainerName)
-{
-  bool ret=false;
-  int len=strlen(ContainerName);
-  if(len>=2)
-    if(strcmp(ContainerName+len-2,"Py")==0)
-      ret=true;
-  return ret;
-}
-
-string Engines_Container_i::BuildContainerNameForNS(const char *ContainerName, const char *hostname)
-{
-  string ret="/Containers/";
-  ret += hostname;
-  ret+="/";
-  if (strlen(ContainerName)== 0)
-    ret+=_defaultContainerName;
-  else
-    ret += ContainerName;
-  return ret;
-}
-
-
-/*
- *  Create one instance of componentName component and register it 
- *  as nameToRegister in naming service
+//=============================================================================
+/*! 
+ *  CORBA method: Create one instance of componentName component 
+ *  and register it as genericRegisterName in naming service
  */
-Engines::Component_ptr Engines_Container_i::instance( const char* nameToRegister,
-                                                     const char* componentName ) {
+//=============================================================================
 
-  _numInstanceMutex.lock() ; // lock on the instance number
-  BEGIN_OF( "Container_i::instance " << componentName ) ;
+// Engines::Component_ptr Engines_Container_i::instance( const char* genericRegisterName,
+//                                                   const char* componentName )
+// {
+//   _numInstanceMutex.lock() ; // lock on the instance number
+//   BEGIN_OF( "Container_i::instance " << componentName ) ;
 
-  string _nameToRegister = nameToRegister;
-  string component_registerName = _containerName + "/" + _nameToRegister;
+//   string _genericRegisterName = genericRegisterName;
+//   string component_registerName = _containerName + "/" + _genericRegisterName;
   
-  Engines::Component_var iobject = Engines::Component::_nil() ;
+//   Engines::Component_var iobject = Engines::Component::_nil() ;
   
-  try {
-    CORBA::Object_var obj = _NS->Resolve( component_registerName.c_str() ) ;
-    if (! CORBA::is_nil( obj ) ) {
-      MESSAGE( "Container_i::instance " << component_registerName.c_str() << " already registered" ) ;
-      iobject = Engines::Component::_narrow( obj ) ;
-    }
-    else{
-      string _compo_name = componentName;
-      string _impl_name = "lib" + _compo_name + "Engine.so";
-      SCRUTE(_impl_name);
+//   try 
+//     {
+//       CORBA::Object_var obj = _NS->Resolve( component_registerName.c_str() ) ;
+//       if (! CORBA::is_nil( obj ) )
+//     {
+//       MESSAGE( "Container_i::instance " << component_registerName.c_str() << " already registered" ) ;
+//       iobject = Engines::Component::_narrow( obj ) ;
+//     }
+//       else
+//     {
+//       string _compo_name = componentName;
+//       string _impl_name = "lib" + _compo_name + "Engine.so";
+//       SCRUTE(_impl_name);
       
-      void* handle;
-      handle = dlopen( _impl_name.c_str() , RTLD_LAZY ) ;
-      
-      if ( handle ) {
-        string factory_name = _compo_name + "Engine_factory";
-        SCRUTE(factory_name) ;
-
-        typedef  PortableServer::ObjectId * (*FACTORY_FUNCTION)
-                                  (CORBA::ORB_ptr,
-                                   PortableServer::POA_ptr, 
-                                   PortableServer::ObjectId *, 
-                                   const char *, 
-                                   const char *) ; 
-        FACTORY_FUNCTION Component_factory = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
-
-        char *error ;
-        if ( (error = dlerror() ) == NULL) {
-             // Instanciate required CORBA object
-            _numInstance++ ;
-             char _aNumI[12];
-             sprintf( _aNumI , "%d" , _numInstance ) ;
-             string instanceName = _compo_name + "_inst_" + _aNumI ;
-             SCRUTE(instanceName);
-
-             PortableServer::ObjectId * id ;
-             id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str() ,
-                                 _nameToRegister.c_str() ) ;
-             // get reference from id
-             obj = _poa->id_to_reference(*id);
-             iobject = Engines::Component::_narrow( obj ) ;
-
-             // register the engine under the name containerName.dir/nameToRegister.object
-             _NS->Register( iobject , component_registerName.c_str() ) ;
-             MESSAGE( "Container_i::instance " << component_registerName.c_str() << " registered" ) ;
-            handle_map[instanceName] = handle;
-        }
-        else{
-            INFOS("Can't resolve symbol: " + factory_name);
-            SCRUTE(error);
-        }  
-      }
-      else{
-       INFOS("Can't load shared library : " << _impl_name);
-       INFOS("error dlopen: " << dlerror());
-      }      
-    }
-  }
-  catch (...) {
-    INFOS( "Container_i::instance exception caught" ) ;
-  }
-  END_OF("Container_i::instance");
-  _numInstanceMutex.unlock() ;
-  return Engines::Component::_duplicate(iobject);
-}
-
+//       void* handle;
+//       handle = dlopen( _impl_name.c_str() , RTLD_LAZY ) ;
+         
+//       if ( handle )
+//         {
+//           string factory_name = _compo_name + "Engine_factory";
+//           SCRUTE(factory_name) ;
+             
+//           typedef  PortableServer::ObjectId * (*FACTORY_FUNCTION)
+//             (CORBA::ORB_ptr,
+//              PortableServer::POA_ptr, 
+//              PortableServer::ObjectId *, 
+//              const char *, 
+//              const char *) ; 
+//           FACTORY_FUNCTION Component_factory = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
+
+//           char *error ;
+//           if ( (error = dlerror() ) == NULL)
+//             {
+//               // Instanciate required CORBA object
+//               _numInstance++ ;
+//               char _aNumI[12];
+//               sprintf( _aNumI , "%d" , _numInstance ) ;
+//               string instanceName = _compo_name + "_inst_" + _aNumI ;
+//               SCRUTE(instanceName);
+                 
+//               PortableServer::ObjectId * id ;
+//               id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str() ,
+//                                          _genericRegisterName.c_str() ) ;
+//               // get reference from id
+//               obj = _poa->id_to_reference(*id);
+//               iobject = Engines::Component::_narrow( obj ) ;
+                 
+//               // register the engine under the name containerName.dir/genericRegisterName.object
+//               _NS->Register( iobject , component_registerName.c_str() ) ;
+//               MESSAGE( "Container_i::instance " << component_registerName.c_str() << " registered" ) ;
+//               _handle_map[instanceName] = handle;
+//             }
+//           else
+//             {
+//               INFOS("Can't resolve symbol: " + factory_name);
+//               SCRUTE(error);
+//             }  
+//         }
+//       else
+//         {
+//           INFOS("Can't load shared library : " << _impl_name);
+//           INFOS("error dlopen: " << dlerror());
+//         }      
+//     }
+//     }
+//   catch (...)
+//     {
+//       INFOS( "Container_i::instance exception caught" ) ;
+//     }
+//   END_OF("Container_i::instance");
+//   _numInstanceMutex.unlock() ;
+//   return Engines::Component::_duplicate(iobject);
+// }
+
+//=============================================================================
+/*! 
+ *  CORBA attribute: Machine Name (hostname without domain extensions)
+ */
+//=============================================================================
+
+// char* Engines_Container_i::machineName()
+// {
+//   string s = GetHostname();
+//   MESSAGE("Engines_Container_i::machineName " << s);
+//    return CORBA::string_dup(s.c_str()) ;
+// }
index 620ca149985180f4ad5e05556e2a2f8757a9a46a..3c4c78b3d3ff390e2b5ae79edc813be422c55c23 100644 (file)
@@ -91,15 +91,24 @@ public:
   void SetCurCpu() ;
   long CpuUsed() ;
   CORBA::Long CpuUsed_impl() ;
+  CORBA::Long getStudyId();
 
+  bool setStudyId(CORBA::Long studyId);
+  static bool isMultiStudy();
+  static bool isMultiInstance();
   static std::string GetDynLibraryName(const char *componentName);
-  static std::string BuildComponentNameForNS(const char *ComponentName, const char *ContainerName, const char *hostname);
+  static std::string BuildComponentNameForNS(const char *ComponentName,
+                                            const char *ContainerName,
+                                            const char *hostname);
 protected:
+  static bool _isMultiStudy;
+  static bool _isMultiInstance;
   std::string _instanceName ;
   std::string _interfaceName ;
   std::string _serviceName ;
   std::string _graphName ;
   std::string _nodeName ;
+  int _studyId; // -1: not initialised; 0: multiStudy; >0: study
   CORBA::ORB_ptr _orb;
   PortableServer::POA_ptr _poa;
   PortableServer::ObjectId * _id;
index 1f0eb93cc523e7fc83a71cc79063edc8d62354bf..6fcfafddafc203d9f5a1b6810634c2fe86cfed48 100644 (file)
@@ -56,33 +56,58 @@ public:
                      bool isServantAloneInProcess = true);
   virtual ~Engines_Container_i();
 
+  // --- CORBA methods
 
-  //! Load component in current container
-  Engines::Component_ptr load_impl(const char* nameToRegister,
-                                  const char* componentName);
+  bool load_component_Library(const char* componentLibraryName);
+
+  Engines::Component_ptr
+  create_component_instance( const char* nameToRegister,
+                            const char* componentLibraryName,
+                            CORBA::Long studyId); // 0 for multiStudy
+
+  Engines::Component_ptr
+  find_component_instance( const char* registeredName,
+                          CORBA::Long studyId); // 0 for multiStudy
+
+  Engines::Component_ptr
+  load_impl(const char* nameToRegister,
+           const char* componentName);
 
-  Engines::Component_ptr instance(const char* nameToRegister,
-                                  const char* componentName);
 
-  //! Unload component from current container
   void remove_impl(Engines::Component_ptr component_i);
   void finalize_removal();
+  void Shutdown();
 
+  char* getHostName();
+  CORBA::Long getPID();
   char* name();
-  char* machineName();
   void ping();
-  void Shutdown();
-  //! Kill current container
+
   bool Kill_impl() ;
 
-  char* getHostName();
-  CORBA::Long getPID();
+  //char* machineName();
+  //Engines::Component_ptr instance(const char* nameToRegister,
+  //                              const char* componentName);
+
+  // --- local C++ methods
+
+  Engines::Component_ptr
+  find_or_create_instance( std::string genericRegisterName,
+                          std::string componentLibraryName);
+
+  Engines::Component_ptr
+  createInstance(std::string genericRegisterName,
+                void *handle,
+                int studyId);
+
   static bool isPythonContainer(const char* ContainerName);
+  static std::string BuildContainerNameForNS(const char *ContainerName,
+                                            const char *hostname);
 
-  static std::string BuildContainerNameForNS(const char *ContainerName, const char *hostname);
-  static const char *_defaultContainerName;
 protected:
 
+  static const char *_defaultContainerName;
+
   SALOME_NamingService *_NS ;
   std::string _library_path;
   std::string _containerName;
@@ -90,16 +115,18 @@ protected:
   PortableServer::POA_var _poa;
   PortableServer::ObjectId * _id ;
   int _numInstance ;
-  std::map<std::string, void *> handle_map ;
-  std::map<std::string, void *> remove_map ;
-  omni_mutex _numInstanceMutex ; // if several threads on the same object
+  std::map<std::string, void *> _library_map; // library names, loaded
+  std::map<std::string,Engines::Component_var> _listInstances_map;
+  std::map<std::string, void *> _handle_map ;
+  std::map<std::string, void *> _remove_map ;
+  omni_mutex _numInstanceMutex ;       // if several threads on the same object
 
   //private: 
 
-  int   _argc ;
+  int    _argc ;
   char** _argv ;
-  long _pid;
-  bool _isServantAloneInProcess;
+  long   _pid;
+  bool   _isServantAloneInProcess;
 };
 
 #endif
index af5848155456dab9d351cc21659f2bee223306c6..00dfee502b12d2bf189e08607f368e5fc23a6a6d 100644 (file)
 #include "SALOME_NamingService.hxx"
 using namespace std;
 
+//=============================================================================
+/*! 
+ *  Constructor
+ */
+//=============================================================================
+
 SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA(SALOME_NamingService *ns)
 {
   _NS = ns;
   //add try catch
-  _NS->Change_Directory("/"); // mpv 250105: current directory may be not root (in SALOMEDS for an example)
-  CORBA::Object_var obj=_NS->Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS);
+  _NS->Change_Directory("/"); // mpv 250105: current directory may be not root 
+                              // (in SALOMEDS for an example)
+  // not enough: set a current directory in naming service is not thread safe
+  // if naming service instance is shared among several threads...
+  // ==> allways use absolute path and dot rely on current directory!
+
+  CORBA::Object_var obj =
+    _NS->Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS);
   ASSERT( !CORBA::is_nil(obj));
   _ContManager=Engines::ContainerManager::_narrow(obj);
 }
 
+//=============================================================================
+/*! 
+ *  Destructor
+ */
+//=============================================================================
+
 SALOME_LifeCycleCORBA::~SALOME_LifeCycleCORBA()
 {
 }
 
-string SALOME_LifeCycleCORBA::ContainerName(
-                                         const char * aComputerContainer ,
-                                         string * theComputer ,
-                                         string * theContainer ) {
-  char * ContainerName = new char [ strlen( aComputerContainer ) + 1 ] ;
-  strcpy( ContainerName , aComputerContainer ) ;
-  string theComputerContainer("/Containers/");
-  char * slash = strchr( ContainerName , '/' ) ;
-  if ( !slash ) {
-    *theComputer = GetHostname() ;
-    theComputerContainer += *theComputer ;
-    theComputerContainer += "/" ;
-    *theContainer = ContainerName ;
-    theComputerContainer += *theContainer ;
-  }
-  else {
-    slash[ 0 ] = '\0' ;
-    slash += 1 ;
-    *theContainer = slash ;
-    if ( !strcmp( ContainerName , "localhost" ) ) {
-      *theComputer = GetHostname() ;
-    }
-    else {
-      *theComputer = ContainerName ;
-    }
-    theComputerContainer += *theComputer ;
-    theComputerContainer += "/" ;
-    theComputerContainer += *theContainer ;
-  }
-  delete [] ContainerName;
-  return theComputerContainer ;
-}
+//=============================================================================
+/*! Public - 
+ *  Look for a fully qualified container name in Naming Service
+ *  \param containerName name of the container to find.
+ *         if containerName begins with "/Containers/" it's used as it is.
+ *            We assume string = "/Containers/machine/aContainerName"
+ *         else
+ *            we assume string = "aContainerName" or "machine/aContainerName".
+ *            string "/Containers/machine/aContainerName" is rebuilt.
+ *            if machine = "localhost", machine replaced by GetHostname()
+ *  \return Container CORBA reference or _nil if not found in Naming Service
+ */
+//=============================================================================
 
-bool SALOME_LifeCycleCORBA::isKnownComponentClass(const char *componentName)
+Engines::Container_ptr
+SALOME_LifeCycleCORBA::FindContainer(const char *containerName)
 {
-
+  ASSERT(_NS != NULL);
+  string cont ;
+  if ( strncmp( containerName , "/Containers/" , 12 ) )
+    { // Compatibility ...
+      string theComputer ;
+      string theContainer ;
+      cont = ContainerName( containerName , &theComputer , &theContainer ) ;
+    }
+  else
+    {
+      cont = containerName ;
+    }
   try
     {
-      CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
-      SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
-       SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
-      SALOME_ModuleCatalog::Acomponent_ptr compoInfo = 
-       Catalog->GetComponent(componentName);
-      if (CORBA::is_nil (compoInfo)) 
+      SCRUTE( cont );
+      CORBA::Object_var obj = _NS->Resolve( cont.c_str() );
+      if( !CORBA::is_nil( obj ) )
        {
-         INFOS("Catalog Error : Component not found in the catalog");
-         return false;
+         return Engines::Container::_narrow( obj ) ;
        }
-      else return true;
     }
   catch (ServiceUnreachable&)
     {
@@ -116,61 +122,98 @@ bool SALOME_LifeCycleCORBA::isKnownComponentClass(const char *componentName)
     {
       INFOS("Caught unknown exception.");
     }
-  return false;
+  return Engines::Container::_nil();
 }
 
-string SALOME_LifeCycleCORBA::ComputerPath(
-                                         const char * theComputer ) {
-  CORBA::String_var path;
-  CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
-  SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
-                    SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
-  try {
-    path = Catalog->GetPathPrefix( theComputer );
-  }
-  catch (SALOME_ModuleCatalog::NotFound&) {
-    INFOS("GetPathPrefix(" << theComputer << ") not found!");
-    path = "" ;
-  }
-  SCRUTE( path ) ;
-  return CORBA::string_dup( path ) ;
+//=============================================================================
+/*! Public - 
+ *  Find and aready existing and registered component instance.
+ *  \param params         machine parameters like type or name...
+ *  \param componentName  the name of component class
+ *  \param studyId        default = 0  : multistudy instance
+ *  \param instanceName   default = "" : to retrieve a specific instance
+ *  \return a CORBA reference of the component instance, or _nil if not found
+ */
+//=============================================================================
+
+Engines::Component_ptr
+SALOME_LifeCycleCORBA::FindComponent(const Engines::MachineParameters& params,
+                                    const char *componentName,
+                                    int studyId,
+                                    const char *instanceName)
+{
+  ASSERT(0);
 }
 
-Engines::Container_ptr SALOME_LifeCycleCORBA::FindContainer(const char *containerName)
+//=============================================================================
+/*! Public - 
+ *  Load a component instance on a container defined by machine parameters
+ *  \param params         machine parameters like type or name...
+ *  \param componentName  the name of component class
+ *  \param studyId        default = 0  : multistudy instance
+ *  \return a CORBA reference of the component instance, or _nil if problem
+ */
+//=============================================================================
+
+Engines::Component_ptr
+SALOME_LifeCycleCORBA::LoadComponent(const Engines::MachineParameters& params,
+                                    const char *componentName,
+                                    int studyId)
 {
-  ASSERT(_NS != NULL);
-  string cont ;
-  if ( strncmp( containerName , "/Containers/" , 12 ) ) { // Compatibility ...
-    string theComputer ;
-    string theContainer ;
-    cont = ContainerName( containerName , &theComputer , &theContainer ) ;
-  }
-  else {
-    cont = containerName ;
-  }
-  try {
+  ASSERT(0);
+}
 
-    SCRUTE( cont );
+//=============================================================================
+/*! Public - 
+ *  Find and aready existing and registered component instance or load a new
+ *  component instance on a container defined by machine parameters
+ *  \param params         machine parameters like type or name...
+ *  \param componentName  the name of component class
+ *  \param studyId        default = 0  : multistudy instance
+ *  \return a CORBA reference of the component instance, or _nil if problem
+ */
+//=============================================================================
 
-    CORBA::Object_var obj = _NS->Resolve( cont.c_str() );
-    if( !CORBA::is_nil( obj ) ) {
-      return Engines::Container::_narrow( obj ) ;
-    }
-  }
-  catch (ServiceUnreachable&) {
-    INFOS("Caught exception: Naming Service Unreachable");
-  }
-  catch (...) {
-    INFOS("Caught unknown exception.");
-  }
-  return Engines::Container::_nil();
+Engines::Component_ptr
+SALOME_LifeCycleCORBA::
+FindOrLoad_Component(const Engines::MachineParameters& params,
+                    const char *componentName,
+                    int studyId)
+{
+  if (! isKnownComponentClass(componentName))
+    return Engines::Component::_nil();
+
+  Engines::MachineList_var listOfMachine =
+    _ContManager->GetFittingResources(params,componentName);
+  Engines::Component_ptr ret=
+    FindComponent(params.container_name,componentName,listOfMachine);
+  if(CORBA::is_nil(ret))
+    return LoadComponent(params.container_name,componentName,listOfMachine);
+  else
+    return ret;
 }
 
-Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component
-                                  (const char *containerName,
-                                  const char *componentName)
+//=============================================================================
+/*! Public - 
+ *  Find and aready existing and registered component instance or load a new
+ *  component instance on a container defined by name
+ *  \param containerName  the name of container, under one of the forms
+ *           - 1 localhost/aContainer
+ *           - 2 aContainer
+ *           - 3 /machine/aContainer
+ *     (not the same rules as FindContainer() method base on protected method
+ *      ContainerName() -- MUST BE CORRECTED --)
+ *  \param componentName  the name of component class
+ *  \return a CORBA reference of the component instance, or _nil if problem
+ */
+//=============================================================================
+
+Engines::Component_ptr
+SALOME_LifeCycleCORBA::FindOrLoad_Component(const char *containerName,
+                                           const char *componentName)
 {
-  if (! isKnownComponentClass(componentName)) return Engines::Component::_nil();
+  if (!isKnownComponentClass(componentName)) return Engines::Component::_nil();
+
   char *stContainer=strdup(containerName);
   string st2Container(stContainer);
   int rg=st2Container.find("/");
@@ -179,50 +222,87 @@ Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component
       stContainer[rg]='\0';
       if(strcmp(stContainer,"localhost")==0)
        {
-         Engines::Component_ptr ret=FindOrLoad_Component(stContainer+rg+1,componentName);
+         Engines::Component_ptr ret=FindOrLoad_Component(stContainer+rg+1,
+                                                         componentName);
          free(stContainer);
          return ret;
        }
+      else ASSERT(0); // no return in that case...
+    }
+  if(rg<0)
+    {
+      //containerName doesn't contain "/" => Local container
+      free(stContainer);
+      Engines::MachineList_var listOfMachine=new Engines::MachineList;
+      listOfMachine->length(1);
+      listOfMachine[0]=CORBA::string_dup(GetHostname().c_str());
+      Engines::Component_ptr ret = FindComponent(containerName,
+                                                componentName,
+                                                listOfMachine.in());
+      if(CORBA::is_nil(ret))
+       return LoadComponent(containerName,componentName,listOfMachine);
+      else
+       return ret;
+    }
+  else 
+    {
+      //containerName contains "/" => Remote container
+      stContainer[rg]='\0';
+      Engines::MachineParameters_var params=new Engines::MachineParameters;
+      params->container_name=CORBA::string_dup(stContainer+rg+1);
+      params->hostname=CORBA::string_dup(stContainer);
+      params->OS=CORBA::string_dup("LINUX");
+      free(stContainer);
+      return FindOrLoad_Component(params,componentName);
     }
-  if(rg<0) {
-    //containerName doesn't contain "/" => Local container
-    free(stContainer);
-    Engines::MachineList_var listOfMachine=new Engines::MachineList;
-    listOfMachine->length(1);
-    listOfMachine[0]=CORBA::string_dup(GetHostname().c_str());
-    Engines::Component_ptr ret=FindComponent(containerName,componentName,listOfMachine.in());
-    if(CORBA::is_nil(ret))
-      return LoadComponent(containerName,componentName,listOfMachine);
-    else
-      return ret;
-  }
-  else {
-    //containerName contains "/" => Remote container
-    stContainer[rg]='\0';
-    Engines::MachineParameters_var params=new Engines::MachineParameters;
-    params->container_name=CORBA::string_dup(stContainer+rg+1);
-    params->hostname=CORBA::string_dup(stContainer);
-    params->OS=CORBA::string_dup("LINUX");
-    free(stContainer);
-    return FindOrLoad_Component(params,componentName);
-  }
 }
 
-Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component(const Engines::MachineParameters& params,
-                                                                  const char *componentName)
+//=============================================================================
+/*! Public -
+ *  Check if the component class is known in module catalog
+ *  \param componentName  the name of component class
+ *  \return true if found, false otherwise
+ */
+//=============================================================================
+
+bool SALOME_LifeCycleCORBA::isKnownComponentClass(const char *componentName)
 {
-  if (! isKnownComponentClass(componentName)) return Engines::Component::_nil();
-  Engines::MachineList_var listOfMachine=_ContManager->GetFittingResources(params,componentName);
-  Engines::Component_ptr ret=FindComponent(params.container_name,componentName,listOfMachine);
-  if(CORBA::is_nil(ret))
-    return LoadComponent(params.container_name,componentName,listOfMachine);
-  else
-    return ret;
+
+  try
+    {
+      CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
+      SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
+       SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
+      SALOME_ModuleCatalog::Acomponent_ptr compoInfo = 
+       Catalog->GetComponent(componentName);
+      if (CORBA::is_nil (compoInfo)) 
+       {
+         INFOS("Catalog Error : Component not found in the catalog");
+         return false;
+       }
+      else return true;
+    }
+  catch (ServiceUnreachable&)
+    {
+      INFOS("Caught exception: Naming Service Unreachable");
+    }
+  catch (...)
+    {
+      INFOS("Caught unknown exception.");
+    }
+  return false;
 }
 
-Engines::Component_ptr SALOME_LifeCycleCORBA::FindComponent(const char *containerName,
-                                                                const char *componentName,
-                                                                const Engines::MachineList& listOfMachines)
+//=============================================================================
+/*! Protected -
+ *  
+ */
+//=============================================================================
+
+Engines::Component_ptr
+SALOME_LifeCycleCORBA::FindComponent(const char *containerName,
+                                    const char *componentName,
+                                    const Engines::MachineList& listOfMachines)
 {
   if (! isKnownComponentClass(componentName)) return Engines::Component::_nil();
   if(containerName[0]!='\0')
@@ -233,8 +313,12 @@ Engines::Component_ptr SALOME_LifeCycleCORBA::FindComponent(const char *containe
       for(unsigned int i=0;i<listOfMachines.length();i++)
        {
          const char *currentMachine=listOfMachines[i];
-         string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,currentMachine);
-         CORBA::Object_var obj = _NS->Resolve(componentNameForNS.c_str());
+         string componentNameForNS = 
+           Engines_Component_i::BuildComponentNameForNS(componentName,
+                                                        containerName,
+                                                        currentMachine);
+         SCRUTE(componentNameForNS);
+         CORBA::Object_var obj=_NS->ResolveFirst(componentNameForNS.c_str());
          if(!CORBA::is_nil(obj))
            {
              machinesOK[lghtOfmachinesOK++]=CORBA::string_dup(currentMachine);
@@ -244,8 +328,12 @@ Engines::Component_ptr SALOME_LifeCycleCORBA::FindComponent(const char *containe
        {
          machinesOK->length(lghtOfmachinesOK);
          CORBA::String_var bestMachine=_ContManager->FindBest(machinesOK);
-         string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine);
-         CORBA::Object_var obj=_NS->Resolve(componentNameForNS.c_str());
+         string componentNameForNS =
+           Engines_Component_i::BuildComponentNameForNS(componentName,
+                                                        containerName,
+                                                        bestMachine);
+         SCRUTE(componentNameForNS);
+         CORBA::Object_var obj=_NS->ResolveFirst(componentNameForNS.c_str());
          return Engines::Component::_narrow(obj);
        }
       else
@@ -253,44 +341,69 @@ Engines::Component_ptr SALOME_LifeCycleCORBA::FindComponent(const char *containe
     }
   else
     {
-      //user specified no container name so trying to find a component in the best machine among listOfMachines
+      //user specified no container name so trying to find a component in
+      //the best machine among listOfMachines
       CORBA::String_var bestMachine=_ContManager->FindBest(listOfMachines);
-      //Normally look at all containers launched on bestMachine to see if componentName is already launched on one of them. To do..
-      string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine);
-      CORBA::Object_var obj = _NS->Resolve(componentNameForNS.c_str());
+      //Normally look at all containers launched on bestMachine to see if
+      //componentName is already launched on one of them. To do..
+      string componentNameForNS =
+       Engines_Component_i::BuildComponentNameForNS(componentName,
+                                                    containerName,
+                                                    bestMachine);
+      SCRUTE(componentNameForNS);
+      CORBA::Object_var obj = _NS->ResolveFirst(componentNameForNS.c_str());
       return Engines::Component::_narrow(obj);
     }
 }
 
-Engines::Component_ptr SALOME_LifeCycleCORBA::LoadComponent(const char *containerName, const char *componentName, const Engines::MachineList& listOfMachines)
+//=============================================================================
+/*! Protected -
+ *
+ */
+//=============================================================================
+
+Engines::Component_ptr
+SALOME_LifeCycleCORBA::LoadComponent(const char *containerName,
+                                    const char *componentName,
+                                    const Engines::MachineList& listOfMachines)
 {
-  Engines::Container_var cont=_ContManager->FindOrStartContainer(containerName,listOfMachines);
+  Engines::Container_var cont=_ContManager->FindOrStartContainer(containerName,
+                                                                listOfMachines);
   string implementation=Engines_Component_i::GetDynLibraryName(componentName);
   return cont->load_impl(componentName, implementation.c_str());
 }
 
 
-Engines::Container_ptr SALOME_LifeCycleCORBA::FindOrStartContainer(
-                                              const string aComputerContainer ,
-                                              const string theComputer ,
-                                              const string theContainer ) {
+//=============================================================================
+/*! Protected -
+ *
+ */
+//=============================================================================
+
+Engines::Container_ptr
+SALOME_LifeCycleCORBA::FindOrStartContainer(const string aComputerContainer ,
+                                           const string theComputer ,
+                                           const string theContainer )
+{
   SCRUTE( aComputerContainer ) ;
   SCRUTE( theComputer ) ;
   SCRUTE( theContainer ) ;
 
-  Engines::Container_var aContainer = FindContainer( aComputerContainer.c_str() ) ;
+  Engines::Container_var aContainer = FindContainer(aComputerContainer.c_str());
 
-  if ( !CORBA::is_nil( aContainer ) ) {
-    return aContainer ;
-  }
+  if ( !CORBA::is_nil( aContainer ) )
+    {
+      return aContainer ;
+    }
 
   Engines::Container_var aFactoryServer ;
 
   bool pyCont = false ;
   int len = theContainer.length() ;
-  if ( !strcmp( &theContainer.c_str()[len-2] , "Py" ) ) {
-    pyCont = true ;
-  }
+  if ( !strcmp( &theContainer.c_str()[len-2] , "Py" ) )
+    {
+      pyCont = true ;
+    }
 
   string addr=_NS->getIORaddr();
   string CMD="SALOME_Container";
@@ -309,16 +422,94 @@ Engines::Container_ptr SALOME_LifeCycleCORBA::FindOrStartContainer(
    *  Wait until the container is registered in Naming Service
    */
   int count = 5 ;
-  while ( CORBA::is_nil( aFactoryServer ) && count ) {
+  while ( CORBA::is_nil( aFactoryServer ) && count )
+    {
       sleep( 1 ) ;
       count-- ;
       if ( count != 10 )
-            MESSAGE( count << ". Waiting for FactoryServer on " << theComputer)
-      aFactoryServer = FindContainer( aComputerContainer.c_str() ) ;
-  }
-  if ( !CORBA::is_nil( aFactoryServer ) ) {
-     return aFactoryServer;
-  }
+       MESSAGE( count << ". Waiting for FactoryServer on " << theComputer)
+         aFactoryServer = FindContainer( aComputerContainer.c_str() ) ;
+    }
+  if ( !CORBA::is_nil( aFactoryServer ) )
+    {
+      return aFactoryServer;
+    }
   MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed") ;
   return Engines::Container::_nil();
 }
+
+//=============================================================================
+/*! Protected -
+ *  \param aComputerContainer container name under one of the forms:
+ *           - 1 aContainer
+ *           - 2 machine/aContainer
+ *  \param theComputer  return computer name:
+ *           - 1 machine = GetHostname() 
+ *           - 2 machine (localhost replaced by GetHostName())
+ *  \param theContainer return container name:
+ *           - 1 aContainer 
+ *           - 2 aContainer
+ *  \return /Containers/machine/aContainer
+ */
+//=============================================================================
+
+string SALOME_LifeCycleCORBA::ContainerName(const char *aComputerContainer ,
+                                           string * theComputer ,
+                                           string * theContainer )
+{
+  char * ContainerName = new char [ strlen( aComputerContainer ) + 1 ] ;
+  strcpy( ContainerName , aComputerContainer ) ;
+  string theComputerContainer("/Containers/");
+  char *slash = strchr( ContainerName , '/' ) ; // first occurence of '/'
+  if ( !slash )    // no '/', only the name, without path
+    {
+      *theComputer = GetHostname() ;
+      theComputerContainer += *theComputer ;
+      theComputerContainer += "/" ;
+      *theContainer = ContainerName ;
+      theComputerContainer += *theContainer ;
+    }
+  else
+    {
+      ASSERT( slash != aComputerContainer); // "/something..." not OK
+      slash[ 0 ] = '\0' ;
+      slash += 1 ;
+      *theContainer = slash ;
+      if ( !strcmp( ContainerName , "localhost" ) )
+       {
+         *theComputer = GetHostname() ;
+       }
+      else
+       {
+         *theComputer = ContainerName ;
+       }
+      theComputerContainer += *theComputer ;
+      theComputerContainer += "/" ;
+      theComputerContainer += *theContainer ;
+    }
+  delete [] ContainerName;
+  return theComputerContainer ;
+}
+
+//=============================================================================
+/*! Protected -
+ *
+ */
+//=============================================================================
+
+string SALOME_LifeCycleCORBA::ComputerPath(const char * theComputer ) 
+{
+  CORBA::String_var path;
+  CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
+  SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
+                    SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
+  try {
+    path = Catalog->GetPathPrefix( theComputer );
+  }
+  catch (SALOME_ModuleCatalog::NotFound&) {
+    INFOS("GetPathPrefix(" << theComputer << ") not found!");
+    path = "" ;
+  }
+  SCRUTE( path ) ;
+  return CORBA::string_dup( path ) ;
+}
index ca91a238ffaf2f72756a930a699929b543d6ee1e..fc4e9d4792c15ca0683d95de6923b8254ff38991 100644 (file)
@@ -44,32 +44,63 @@ class SALOME_LifeCycleCORBA
 public:
   SALOME_LifeCycleCORBA(SALOME_NamingService *ns);
   virtual ~SALOME_LifeCycleCORBA();
-  Engines::Container_ptr FindContainer(const char *containerName); // for supervision
-  Engines::Component_ptr FindOrLoad_Component(const Engines::MachineParameters& params,
-                                             const char *componentName);
-  Engines::Component_ptr FindOrLoad_Component(const char *containerName,
-                                             const char *componentName);
+
+  Engines::Container_ptr 
+  FindContainer(const char *containerName); // for supervision
+
+  Engines::Component_ptr
+  FindComponent(const Engines::MachineParameters& params,
+               const char *componentName,
+               int studyId=0,
+               const char *instanceName="");
+
+  Engines::Component_ptr
+  LoadComponent(const Engines::MachineParameters& params,
+               const char *componentName,
+               int studyId=0);
+
+  Engines::Component_ptr 
+  FindOrLoad_Component(const Engines::MachineParameters& params,
+                      const char *componentName,
+                      int studyId=0);
+
+  Engines::Component_ptr
+  FindOrLoad_Component(const char *containerName,
+                      const char *componentName); // for compatibility
+  
   bool isKnownComponentClass(const char *componentName);
+
 protected:
-  //! Establish if a component called "componentName" in a container called "containerName" exists among the list of resources
-  //! in "listOfMachines". This method uses Naming Service to find the component.
-  Engines::Component_ptr FindComponent(const char *containerName,
-                                           const char *componentName,
-                                           const Engines::MachineList& listOfMachines);
 
-  Engines::Component_ptr LoadComponent(const char *containerName, const char *componentName, const Engines::MachineList& listOfMachines);
+  /*! Establish if a component called "componentName" in a container called
+   *  "containerName"
+   *  exists among the list of resources in "listOfMachines".
+   *  This method uses Naming Service to find the component.
+   */
+  Engines::Component_ptr 
+  FindComponent(const char *containerName,
+               const char *componentName,
+               const Engines::MachineList& listOfMachines);
 
+  Engines::Component_ptr
+  LoadComponent(const char *containerName,
+               const char *componentName,
+               const Engines::MachineList& listOfMachines);
+  
   SALOME_NamingService *_NS;
   Engines::ContainerManager_var _ContManager;
   
   //private:
+
   std::string ContainerName( const char * aComputerContainer ,
                             std::string * theComputer ,
                             std::string * theContainer ) ;
   std::string ComputerPath( const char * theComputer ) ;
-  Engines::Container_ptr FindOrStartContainer(const std::string aComputerContainer ,
-                                              const std::string theComputer ,
-                                              const std::string theContainer ) ;
+
+  Engines::Container_ptr 
+  FindOrStartContainer(const std::string aComputerContainer ,
+                      const std::string theComputer ,
+                      const std::string theContainer ) ;
 } ;
 
 #endif
index fcdf75f135f3c1246a39f144eb395dfb3b7953a1..6108b2dc31961f228ac11b0a027af3ac47bdb1c9 100644 (file)
@@ -66,7 +66,6 @@ void NamingService_WaitForServerReadiness(SALOME_NamingService* NS,
        {
          if (serverName.length() == 0)
            {
-             //string curdir = NS->Current_Directory(); // to wait for naming service
              string dummyadr = NS->getIORaddr(); // to wait for naming service
              found = 1;
              break; // naming service found
index 4beb6d4e3606c5d5463cdfee7f501900dc6ee2c3..47cab4451bc2a2caae784f2a62859bb79bba376d 100644 (file)
@@ -80,7 +80,8 @@ SALOME_NamingService::~SALOME_NamingService()
 
 void SALOME_NamingService::init_orb(CORBA::ORB_ptr orb)
 {
-  // MESSAGE("SALOME_NamingService initialisation");
+  MESSAGE("SALOME_NamingService initialisation");
+  Utils_Locker lock(&_myMutex);
   _orb = orb ;
   _initialize_root_context();
 }
@@ -100,7 +101,8 @@ void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
                                    const char* Path) 
   throw(ServiceUnreachable)
 {
-  // MESSAGE("BEGIN OF Register: "<< Path);
+  MESSAGE("BEGIN OF Register: "<< Path);
+  Utils_Locker lock(&_myMutex);
   int dimension_Path = strlen(Path) + 1;
   char** resultat_resolve_Path = new char* [dimension_Path];
 
@@ -298,7 +300,8 @@ void SALOME_NamingService::Register(CORBA::Object_ptr ObjRef,
 CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
   throw(ServiceUnreachable)
 {
-  //MESSAGE("BEGIN OF Resolve: " << Path);
+  MESSAGE("BEGIN OF Resolve: " << Path);
+  Utils_Locker lock(&_myMutex);
   int dimension_Path = strlen(Path) + 1;
   char** resultat_resolve_Path = new char* [dimension_Path];
 
@@ -368,6 +371,53 @@ CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
   return _obj;
 }
 
+//----------------------------------------------------------------------
+/*! Function : ResolveFirst 
+ *  Purpose  : method to get an ObjRef with a symbolic name
+ * \param Path const char* argument like "/path/name"
+ *  search the fist reference like "/path(.dir)/name*(.kind)"
+ *  If the NamingService is out, the exception ServiceUnreachable is thrown 
+ * \return the object reference
+ */
+//----------------------------------------------------------------------
+
+CORBA::Object_ptr SALOME_NamingService::ResolveFirst(const char* Path)
+  throw(ServiceUnreachable)
+{
+  MESSAGE("ResolveFirst");
+  Utils_Locker lock(&_myMutex);
+  SCRUTE(Path);
+  string thePath =Path;
+  string basePath ="/";
+  string name = thePath;
+  string::size_type idx = thePath.rfind('/');
+  if (idx != string::npos) // at least one '/' found
+    {
+      basePath = thePath.substr(0,idx);
+      name = thePath.substr(idx+1);
+      SCRUTE(basePath);
+    }
+  SCRUTE(name);
+  CORBA::Object_ptr obj = CORBA::Object::_nil();
+  bool isOk = Change_Directory(basePath.c_str());
+  if (isOk)
+    {
+      vector<string> listElem = list_directory();
+      vector<string>::iterator its = listElem.begin();
+      while (its != listElem.end())
+       {
+         MESSAGE(*its);
+         if ((*its).find(name) == 0)
+           {
+             //string instance = basePath + "/" + *its;
+             return Resolve((*its).c_str());
+           }
+         its++;
+       }
+    }
+  return obj;
+}
+
 //----------------------------------------------------------------------
 /*!  Function : Find
  *  Purpose  : method to research a name from the current directory 
@@ -384,7 +434,8 @@ CORBA::Object_ptr SALOME_NamingService::Resolve(const char* Path)
 int SALOME_NamingService::Find(const char* name)
   throw(ServiceUnreachable)
 {
-  // MESSAGE("BEGIN OF Find " << name);
+  MESSAGE("BEGIN OF Find " << name);
+  Utils_Locker lock(&_myMutex);
   CORBA::Long occurence_number = 0 ; 
   try
     {
@@ -411,7 +462,8 @@ int SALOME_NamingService::Find(const char* name)
 bool SALOME_NamingService::Create_Directory(const char* Path)
   throw(ServiceUnreachable)
 {
-  //MESSAGE("BEGIN OF Create_Directory");
+  MESSAGE("BEGIN OF Create_Directory");
+  Utils_Locker lock(&_myMutex);
   int dimension_Path = strlen(Path) + 1;
   char** resultat_resolve_Path= new char* [dimension_Path];;
   CORBA::Boolean _return_code = true ;
@@ -525,7 +577,8 @@ bool SALOME_NamingService::Create_Directory(const char* Path)
 bool SALOME_NamingService::Change_Directory(const char* Path)
   throw(ServiceUnreachable)
 {
-  //MESSAGE("BEGIN OF Change_Directory " << Path);
+  MESSAGE("BEGIN OF Change_Directory " << Path);
+  Utils_Locker lock(&_myMutex);
   int dimension_Path = strlen(Path) + 1;
   char** resultat_resolve_Path = new char* [dimension_Path];
   CORBA::Boolean _return_code = true ;
@@ -617,7 +670,8 @@ bool SALOME_NamingService::Change_Directory(const char* Path)
 char* SALOME_NamingService::Current_Directory()
   throw(ServiceUnreachable)
 {
-  //MESSAGE("BEGIN OF Current_Directory");  
+  MESSAGE("BEGIN OF Current_Directory");  
+  Utils_Locker lock(&_myMutex);
 
   CosNaming::NamingContext_var _ref_context = _current_context;
 
@@ -672,6 +726,7 @@ void SALOME_NamingService::list()
   throw(ServiceUnreachable)
 {
   MESSAGE("Begin of list");
+  Utils_Locker lock(&_myMutex);
   CosNaming::BindingList_var _binding_list;
   CosNaming::BindingIterator_var _binding_iterator;
   unsigned long nb=0 ; // for using only the BindingIterator to access the bindings
@@ -748,6 +803,8 @@ vector<string> SALOME_NamingService::list_directory()
 vector<string> SALOME_NamingService::list_directory_recurs()
     throw(ServiceUnreachable)
 {
+  MESSAGE("list_directory_recurs");
+  Utils_Locker lock(&_myMutex);
   vector<string> _list ;
   char *currentDir=Current_Directory();
   _list_directory_recurs(_list,0,currentDir);
@@ -768,6 +825,7 @@ void SALOME_NamingService::Destroy_Name(const char* Path)
   throw(ServiceUnreachable)
 {
   MESSAGE("BEGIN OF Destroy_Name");
+  Utils_Locker lock(&_myMutex);
   int dimension_Path = strlen(Path) + 1;
   char** resultat_resolve_Path = new char* [dimension_Path];
 
@@ -889,6 +947,7 @@ void SALOME_NamingService::Destroy_Directory(const char* Path)
   throw(ServiceUnreachable)
 {
   MESSAGE("BEGIN OF Destroy_Directory");
+  Utils_Locker lock(&_myMutex);
   int dimension_Path = strlen(Path) + 1;
   char** resultat_resolve_Path = new char* [dimension_Path];
 
@@ -1383,6 +1442,7 @@ void SALOME_NamingService::_list_directory_recurs(vector<string>& myList, const
 
 //----------------------------------------------------------------------
 
-char * SALOME_NamingService::getIORaddr(){
+char * SALOME_NamingService::getIORaddr()
+{
    return _orb->object_to_string(_root_context);
 }
index db9c39e17865a0a55a776342536b465ec57bfac2..1f32054983cbc9f9a70413852b4590986bbb55cb 100644 (file)
@@ -33,6 +33,7 @@
 #include <CORBA.h>
 #include <vector>
 #include <string>
+#include "Utils_Mutex.hxx"
 
 //class ServiceUnreachable;
 #include "ServiceUnreachable.hxx"
@@ -60,6 +61,10 @@ public:
   CORBA::Object_ptr Resolve(const char* Path)
     throw( ServiceUnreachable); 
 
+  //! method to get an ObjRef, given a symbolic name without instance suffix "/Path/Name*.kind"
+  CORBA::Object_ptr ResolveFirst(const char* Path)
+    throw( ServiceUnreachable); 
+
   //! method to research a name from the naming service's current directory 
   int Find(const char* name)
     throw(ServiceUnreachable);
@@ -101,6 +106,7 @@ public:
   char * getIORaddr();
 
 protected:
+  Utils_Mutex _myMutex;
   CORBA::ORB_ptr _orb;
   CosNaming::NamingContext_var _root_context, _current_context;
 
index d3bf23b36c0972a8162742eb41829139ab6daedc..1b01f31526f915d3d57b6f8559e13014e55cf637 100644 (file)
@@ -385,7 +385,7 @@ void Session_ServerThread::ActivateContainer(int argc,
        }
       
       Engines_Container_i * myContainer 
-       = new Engines_Container_i(_orb, factory_poa, containerName , argc , argv , true , false);
+       = new Engines_Container_i(_orb, _root_poa, containerName , argc , argv , true , false);
     }
   catch(CORBA::SystemException&)
     {
index 413fd2fa04bfecbc49d694c2d70ca6c6cdd66272..64772b14e21b8c234f8321dda49f46044d83c842 100644 (file)
@@ -26,6 +26,7 @@
 //  Module : SALOME
 //  $Header$
 
+#define private protected
 #include "utilities.h"
 #include "SALOME_TestComponent_i.hxx"
 #include <stdio.h>
@@ -40,10 +41,10 @@ Engines_TestComponent_i::Engines_TestComponent_i(CORBA::ORB_ptr orb,
                                                 const char *interfaceName) :
   Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
 {
-  MESSAGE("activate object")
+  MESSAGE("activate object");
   _thisObj = this ;
   _id = _poa->activate_object(_thisObj);
-  //SCRUTE(this)
+  SCRUTE(pd_refCount);
 }
 
 Engines_TestComponent_i::Engines_TestComponent_i()
@@ -52,12 +53,14 @@ Engines_TestComponent_i::Engines_TestComponent_i()
 
 Engines_TestComponent_i::~Engines_TestComponent_i()
 {
+  MESSAGE("~Engines_TestComponent_i()");
 }
 
 char* Engines_TestComponent_i::Coucou(CORBA::Long L)
 {
   char s[100];
   sprintf(s, "TestComponent_i : L = %ld", (long) L);
+  SCRUTE(pd_refCount);
 
   return CORBA::string_dup(s);
 }
index b668b740b8f39dc939a726b279f07de7dfe219ee..4bd9135fe320ded562add23a8d657c3737429568 100644 (file)
@@ -34,6 +34,7 @@
 #include CORBA_CLIENT_HEADER(SALOME_TestComponent)
 
 #include "SALOME_NamingService.hxx"
+#include "NamingService_WaitForServerReadiness.hxx"
 #include "OpUtil.hxx"
 #include "Utils_ORB_INIT.hxx"
 #include "Utils_SINGLETON.hxx"
@@ -59,10 +60,23 @@ static ostream& operator<<(ostream& os, const CORBA::Exception& e)
   return os;
 }
 
+Engines::TestComponent_ptr create_intance(Engines::Container_ptr iGenFact)
+{
+  bool isLib =
+    iGenFact->load_component_Library("libSalomeTestComponentEngine.so");
+  ASSERT(isLib);
+  CORBA::Object_var obj =
+    iGenFact->create_component_instance("SalomeTestComponent",
+                                       "libSalomeTestComponentEngine.so",
+                                       0);
+  Engines::TestComponent_var anInstance = Engines::TestComponent::_narrow(obj);
+  MESSAGE("create anInstance");
+  SCRUTE(anInstance->instanceName());
+  return anInstance._retn();
+}
 
 int main (int argc, char * argv[])
 {
-
   // Initializing omniORB
   ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
   CORBA::ORB_var &orb = init( argc , argv ) ;
@@ -70,115 +84,30 @@ int main (int argc, char * argv[])
 
   try
     {
-
-
-    
-      // use IOR to find container
-      //if (argc != 2) { return 1; }
-      //CORBA::Object_var obj = orb->string_to_object(argv[1]);
-      //Engines::Container_var iGenFact = Engines::Container::_narrow(obj);
-
-      // Obtain a reference to the root POA
-      //
-      long TIMESleep = 250000000;
-      int NumberOfTries = 40;
-      int a;
-      timespec ts_req;
-      ts_req.tv_nsec=TIMESleep;
-      ts_req.tv_sec=0;
-      timespec ts_rem;
-      ts_rem.tv_nsec=0;
-      ts_rem.tv_sec=0;
-      CosNaming::NamingContext_var inc;
-      PortableServer::POA_var poa;
-      CORBA::Object_var theObj;
-      CORBA::Object_var obj;
-      CORBA::Object_var object;
-      SALOME_NamingService &naming = *SINGLETON_<SALOME_NamingService>::Instance() ;
-      int TEST_CONTAINER=0;
-      const char * Env = getenv("USE_LOGGER"); 
-      int EnvL =0;
-      if ((Env!=NULL) && (strlen(Env)))
-       EnvL=1;
-      CosNaming::Name name;
-      name.length(1);
-      name[0].id=CORBA::string_dup("Logger");    
-      PortableServer::POAManager_var manager; 
-      for (int i = 1; i<=NumberOfTries; i++)
-       {
-         if (i!=1) 
-           a=nanosleep(&ts_req,&ts_rem);
-         try
-           { 
-             obj = orb->resolve_initial_references("RootPOA");
-             if(!CORBA::is_nil(obj))
-               poa = PortableServer::POA::_narrow(obj);
-             if(!CORBA::is_nil(poa))
-               manager = poa->the_POAManager();
-             if(!CORBA::is_nil(orb)) 
-               theObj = orb->resolve_initial_references("NameService");
-             if (!CORBA::is_nil(theObj))
-               inc = CosNaming::NamingContext::_narrow(theObj);
-           }
-         catch( CORBA::SystemException& )
-           {
-             INFOS( "Test Container: CORBA::SystemException: Unable to contact the Naming Service" )
-               }
-         if(!CORBA::is_nil(inc))
-           {
-             MESSAGE( "Test Container: Naming Service was found" )
-               if(EnvL==1)
-                 {
-                   for(int j=1; j<=NumberOfTries; j++)
-                     {
-                       if (j!=1) 
-                         a=nanosleep(&ts_req, &ts_rem);
-                       try
-                         {
-                           object = inc->resolve(name);
-                         }
-                       catch(CosNaming::NamingContext::NotFound)
-                         {
-                           INFOS( "Test Container: Logger Server wasn't found" );
-                         }
-                       catch(...)
-                         {
-                           INFOS( "Test Container: Unknown exception" );
-                         }
-                       if (!CORBA::is_nil(object))
-                         {
-                           MESSAGE( "Test Container: Loger Server was found" );
-                           TEST_CONTAINER=1;
-                           break;
-                         }
-                     }
-                 }
-           }
-         if ((TEST_CONTAINER==1)||((EnvL==0)&&(!CORBA::is_nil(inc))))
-            break;
-       }
-
-      // Use Name Service to find container
       SALOME_NamingService _NS(orb) ;
       string containerName = "/Containers/" ;
       string hostName = GetHostname();
       containerName += hostName + "/FactoryServer";
+      NamingService_WaitForServerReadiness(&_NS,containerName);
 
-      obj = _NS.Resolve(containerName.c_str()) ;
+      CORBA::Object_var obj = _NS.Resolve(containerName.c_str()) ;
       Engines::Container_var iGenFact = Engines::Container::_narrow(obj);
 
-      Engines::TestComponent_var m1;
+      int nbInstances = 5;
+
+      vector<Engines::TestComponent_var> instances(nbInstances);
     
-      for (int iter = 0; iter < 3 ; iter++)
+      MESSAGE("------------------------------- create instances ");
+      for (int iter = 0; iter < nbInstances ; iter++)
        {
-         MESSAGE("----------------------------------------------------" << iter);   
-          string dirn = getenv("KERNEL_ROOT_DIR");
-          dirn += "/lib/salome/libSalomeTestComponentEngine.so";
-          obj = iGenFact->load_impl("SalomeTestComponent",dirn.c_str());
-         m1 = Engines::TestComponent::_narrow(obj);
-         MESSAGE("recup m1");
-         SCRUTE(m1->instanceName());
+         instances[iter] = create_intance(iGenFact);
+       }
 
+      MESSAGE("------------------------------ set env instances ");
+      for (int iter = 0; iter < nbInstances ; iter++)
+       {
+         Engines::TestComponent_var anInstance = instances[iter];
+         SCRUTE(anInstance->instanceName());
          Engines::FieldsDict_var dico = new Engines::FieldsDict;
          dico->length(3);
          dico[0].key=CORBA::string_dup("key_0");
@@ -186,14 +115,18 @@ int main (int argc, char * argv[])
          dico[1].key=CORBA::string_dup("key_1");
          dico[1].value <<=(CORBA::UShort)72;
          dico[2].key=CORBA::string_dup("key_2");
-         dico[2].value <<="value_2";
-         m1->setProperties(dico);
-
-         MESSAGE("Coucou " << m1->Coucou(1L));
-
-         m1->Setenv();
+         dico[2].value <<=(CORBA::ULong)iter;
+         anInstance->setProperties(dico);
+         MESSAGE("Coucou " << anInstance->Coucou(iter));
+         anInstance->Setenv();
+       }
 
-         Engines::FieldsDict_var dico2 =  m1->getProperties();
+      MESSAGE("---------------------------------- get instances ");
+      for (int iter = 0; iter < nbInstances ; iter++)
+       {
+         Engines::TestComponent_var anInstance = instances[iter];
+         SCRUTE(anInstance->instanceName());
+         Engines::FieldsDict_var dico2 =  anInstance->getProperties();
          for (CORBA::ULong i=0; i<dico2->length(); i++)
            {
              MESSAGE("dico2["<<i<<"].key="<<dico2[i].key);
@@ -205,14 +138,20 @@ int main (int argc, char * argv[])
                  MESSAGE("dico2["<<i<<"].value="<<value);
                }
            }
+       }
 
-         iGenFact->remove_impl(m1) ;
+      MESSAGE("------------------------------- remove instances ");
+      for (int iter = 0; iter < nbInstances ; iter++)
+       {
+         Engines::TestComponent_var anInstance = instances[iter];
+         SCRUTE(anInstance->instanceName());
+         iGenFact->remove_impl(anInstance) ;
          //iGenFact->finalize_removal() ; // unpredictable results ...
-          sleep(5);
-       }    
+       } 
+   
       // Clean-up.
       iGenFact->finalize_removal() ;
-      orb->destroy();
+      orb->shutdown(0);
     }
   catch(CORBA::COMM_FAILURE& ex) {
     INFOS("Caught system exception COMM_FAILURE -- unable to contact the object.")