]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
- Start of a new version of PACO integration with SALOME
authorribes <ribes>
Thu, 12 Mar 2009 16:08:47 +0000 (16:08 +0000)
committerribes <ribes>
Thu, 12 Mar 2009 16:08:47 +0000 (16:08 +0000)
25 files changed:
idl/DSC_Engines.idl
idl/DSC_Engines.xml
idl/Makefile.am
idl/SALOME_Component.idl
idl/SALOME_Component.xml
idl/SALOME_PACOExtension.idl [new file with mode: 0644]
idl/SALOME_PACOExtension.xml [new file with mode: 0644]
idl/SALOME_ParamPorts.idl [new file with mode: 0644]
idl/SALOME_ParamPorts.xml [new file with mode: 0644]
idl/SALOME_Ports.idl
idl/SALOME_Ports.xml
src/DSC/ParallelDSC/ParallelDSC_i.hxx
src/DSC/ParallelDSC/Param_Double_Port_provides_i.hxx
src/DSC/ParallelDSC/Param_Double_Port_uses_i.hxx
src/ParallelContainer/Makefile.am
src/ParallelContainer/Parallel_Salome_file_i.hxx
src/ParallelContainer/SALOME_ParallelComponent_i.hxx
src/ParallelContainer/SALOME_ParallelContainerProxyDummy.cxx
src/ParallelContainer/SALOME_ParallelContainerProxyMpi.cxx
src/ParallelContainer/SALOME_ParallelContainerProxy_i.cxx
src/ParallelContainer/SALOME_ParallelContainerProxy_i.hxx
src/ParallelContainer/SALOME_ParallelContainer_i.cxx
src/ParallelContainer/SALOME_ParallelContainer_i.hxx
src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.cxx [new file with mode: 0644]
src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.hxx [new file with mode: 0644]

index cbe349e271c9a7115260947ff2596f76088caea9..f379113626c01bc16c55bf4e389dc26a1fc26cf1 100644 (file)
@@ -356,30 +356,6 @@ module Engines {
      */
     boolean init_service(in string service_name);
   };
-
-/*--------------------------------------------------------------------------------------------*/
-
-  /*! \brief Interface of a Parallel_DSC component.
-    This interface defines the operations needed to add a paco++ port 
-    into a parallel DSC component.
-  */
-  interface Parallel_DSC : Engines::Superv_Component, Engines::Parallel_Component {
-
-    /*!
-      This operation gives the proxy node of a paco++ port to all the nodes.
-      Only a node of the parallel component is going to add a proxy object 
-      with an internal method.
-
-      \param ref provides proxy port's reference.
-      \param provides_port_name provides port's name.
-
-      \see Engines_ParallelDSC_i::add_parallel_provides_proxy_port
-     */
-    void set_paco_proxy(in Object ref, 
-                       in string provides_port_name,
-                       in Ports::PortProperties port_prop);
-                       
-  };  
 };
 
 #endif
index 9148b8b18b890905a5b22354a84fd43414f4ab80..0f3ec937fbe2b8f20323413d8813dbdf31918881 100644 (file)
    <Type>distributed</Type>
  </Method>
  </Interface>
- <Interface>
-   <Name>Parallel_DSC</Name>
-   <Method>
-     <Name>set_paco_proxy</Name>
-     <Type>distributed</Type>
-   </Method>
- </Interface>
  <Interface>
    <Name>Superv_Component</Name>
    <Method>
index 13a90697c7f36b1f936d1f19e0264f984fca7e42..d724adcc6a68f716e1075dae963703625346fb6f 100644 (file)
@@ -47,7 +47,9 @@ BASEIDL_FILES = \
   DSC_Engines.idl \
   SALOME_Ports.idl \
   Calcium_Ports.idl \
-  Palm_Ports.idl
+  Palm_Ports.idl \
+  SALOME_PACOExtension.idl \
+  SALOME_ParamPorts.idl
 
 MPIIDL_FILES = \
   SALOME_MPIObject.idl \
@@ -65,7 +67,8 @@ OTHER_IDL_FILES = \
 
 # all the idl files are needed for make dist
 EXTRA_DIST= $(BASEIDL_FILES) $(MPIIDL_FILES) $(OTHER_IDL_FILES) \
-           SALOME_Component.xml DSC_Engines.xml SALOME_Ports.xml
+           SALOME_Component.xml DSC_Engines.xml SALOME_Ports.xml \
+           SALOME_PACOExtension.xml SALOME_ParamPorts.xml
 
 # This variable defines the files to be installed
 salomeidl_DATA = $(IDL_FILES)
@@ -93,7 +96,9 @@ BASEIDL_SOURCES =\
   DSC_EnginesSK.cc \
   SALOME_PortsSK.cc \
   Calcium_PortsSK.cc \
-  Palm_PortsSK.cc
+  Palm_PortsSK.cc \
+  SALOME_PACOExtensionSK.cc \
+  SALOME_ParamPortsSK.cc
 
 DYNIDL_SRCS = \
   SALOME_PortsDynSK.cc  Calcium_PortsDynSK.cc     SALOME_ContainerManagerDynSK.cc \
@@ -101,7 +106,7 @@ DYNIDL_SRCS = \
   SALOMEDSDynSK.cc      SALOME_SessionDynSK.cc    SALOME_RessourcesCatalogDynSK.cc \
   DSC_EnginesDynSK.cc   SALOME_ComponentDynSK.cc  SALOME_GenericObjDynSK.cc \
   Palm_PortsDynSK.cc    SALOME_ExceptionDynSK.cc  SALOMEDS_AttributesDynSK.cc \
-  LoggerDynSK.cc
+  LoggerDynSK.cc        SALOME_PACOExtensionDynSK.cc SALOME_ParamPortsDynSK.cc
 
 MPIIDL_SOURCES = \
   SALOME_MPIObjectSK.cc \
@@ -127,82 +132,96 @@ salomeinclude_DATA= $(STATIDL_SOURCES:%SK.cc=%.hh)
 if WITH_PACO_PARALLEL
 PAR = SALOME_ComponentPaCO.hxx SALOME_ComponentPaCO.cxx \
       SALOME_PortsPaCO.hxx SALOME_PortsPaCO.cxx \
-      DSC_EnginesPaCO.hxx DSC_EnginesPaCO.cxx
+      DSC_EnginesPaCO.hxx DSC_EnginesPaCO.cxx \
+      SALOME_PACOExtensionPaCO.hxx SALOME_PACOExtensionPaCO.cxx \
+      SALOME_ParamPortsPaCO.hxx SALOME_ParamPortsPaCO.cxx
 
 PAR_INCLUDES = SALOME_Exception.hxx SALOME_GenericObj.hxx SALOMEDS.hxx
 
 PAR_LIB = libSalomeParallelIDLKernel.la
 
-IDL_PACO      = SALOME_ComponentPaCO.idl SALOME_PortsPaCO.idl DSC_EnginesPaCO.idl
+IDL_PACO = SALOME_ComponentPaCO.idl SALOME_PortsPaCO.idl DSC_EnginesPaCO.idl \
+          SALOME_ParamPorts.idl SALOME_PACOExtension.idl
 
 GEN_PACO = SALOME_ComponentPaCO_Engines_Container_server.cxx \
           SALOME_ComponentPaCO_Engines_Container_client.cxx \
           SALOME_ComponentPaCO_Engines_Component_server.cxx \
           SALOME_ComponentPaCO_Engines_Component_client.cxx \
-          SALOME_ComponentPaCO_Engines_Parallel_Component_server.cxx \
-          SALOME_ComponentPaCO_Engines_Parallel_Component_client.cxx \
           SALOME_ComponentPaCO_Engines_fileTransfer_server.cxx \
           SALOME_ComponentPaCO_Engines_fileTransfer_client.cxx \
           SALOME_ComponentPaCO_Engines_Salome_file_server.cxx \
           SALOME_ComponentPaCO_Engines_Salome_file_client.cxx \
-          SALOME_ComponentPaCO_Engines_Parallel_Salome_file_server.cxx \
-          SALOME_ComponentPaCO_Engines_Parallel_Salome_file_client.cxx \
           SALOME_PortsPaCO_Ports_Port_server.cxx \
           SALOME_PortsPaCO_Ports_Port_client.cxx \
           SALOME_PortsPaCO_Ports_Data_Port_server.cxx \
           SALOME_PortsPaCO_Ports_Data_Port_client.cxx \
-          SALOME_PortsPaCO_Ports_Param_Double_Port_server.cxx \
-          SALOME_PortsPaCO_Ports_Param_Double_Port_client.cxx \
           DSC_EnginesPaCO_Engines_DSC_server.cxx \
           DSC_EnginesPaCO_Engines_DSC_client.cxx \
           DSC_EnginesPaCO_Engines_Superv_Component_server.cxx \
           DSC_EnginesPaCO_Engines_Superv_Component_client.cxx \
-          DSC_EnginesPaCO_Engines_Parallel_DSC_server.cxx \
-          DSC_EnginesPaCO_Engines_Parallel_DSC_client.cxx
+          SALOME_PACOExtensionPaCO_Engines_Parallel_Component_server.cxx \
+          SALOME_PACOExtensionPaCO_Engines_Parallel_Component_client.cxx \
+          SALOME_PACOExtensionPaCO_Engines_PACO_Container_server.cxx \
+          SALOME_PACOExtensionPaCO_Engines_PACO_Container_client.cxx \
+          SALOME_PACOExtensionPaCO_Engines_Parallel_Salome_file_server.cxx \
+          SALOME_PACOExtensionPaCO_Engines_Parallel_Salome_file_client.cxx \
+          SALOME_PACOExtensionPaCO_Engines_Parallel_DSC_server.cxx \
+          SALOME_PACOExtensionPaCO_Engines_Parallel_DSC_client.cxx \
+          SALOME_ParamPortsPaCO_Ports_Param_Double_Port_server.cxx \
+          SALOME_ParamPortsPaCO_Ports_Param_Double_Port_client.cxx
 
 INCLUDES_PACO = SALOME_ComponentPaCO_Engines_Container_server.hxx \
                SALOME_ComponentPaCO_Engines_Container_client.hxx \
-                SALOME_ComponentPaCO_Engines_Component_server.hxx \
+               SALOME_ComponentPaCO_Engines_Component_server.hxx \
                SALOME_ComponentPaCO_Engines_Component_client.hxx \
-                SALOME_ComponentPaCO_Engines_Parallel_Component_server.hxx \
-               SALOME_ComponentPaCO_Engines_Parallel_Component_client.hxx \
                SALOME_ComponentPaCO_Engines_fileTransfer_server.hxx \
                SALOME_ComponentPaCO_Engines_fileTransfer_client.hxx \
                SALOME_ComponentPaCO_Engines_Salome_file_server.hxx \
                SALOME_ComponentPaCO_Engines_Salome_file_client.hxx \
-               SALOME_ComponentPaCO_Engines_Parallel_Salome_file_server.hxx \
-               SALOME_ComponentPaCO_Engines_Parallel_Salome_file_client.hxx \
                SALOME_ComponentPaCO.hxx \
                SALOME_Component.hxx \
                SALOME_PortsPaCO_Ports_Port_server.hxx \
                SALOME_PortsPaCO_Ports_Port_client.hxx \
                SALOME_PortsPaCO_Ports_Data_Port_server.hxx \
                SALOME_PortsPaCO_Ports_Data_Port_client.hxx \
-               SALOME_PortsPaCO_Ports_Param_Double_Port_server.hxx \
-               SALOME_PortsPaCO_Ports_Param_Double_Port_client.hxx \
                SALOME_PortsPaCO.hxx \
                SALOME_Ports.hxx \
                DSC_EnginesPaCO_Engines_DSC_server.hxx \
                DSC_EnginesPaCO_Engines_DSC_client.hxx \
-                DSC_EnginesPaCO_Engines_Superv_Component_server.hxx \
+               DSC_EnginesPaCO_Engines_Superv_Component_server.hxx \
                DSC_EnginesPaCO_Engines_Superv_Component_client.hxx \
-               DSC_EnginesPaCO_Engines_Parallel_DSC_server.hxx \
-               DSC_EnginesPaCO_Engines_Parallel_DSC_client.hxx \
                DSC_EnginesPaCO.hxx \
-               DSC_Engines.hxx
-
-XML           = SALOME_Component.xml DSC_Engines.xml SALOME_Ports.xml
+               DSC_Engines.hxx \
+               SALOME_PACOExtensionPaCO_Engines_Parallel_Component_server.hxx \
+               SALOME_PACOExtensionPaCO_Engines_Parallel_Component_client.hxx \
+               SALOME_PACOExtensionPaCO_Engines_PACO_Container_server.hxx \
+               SALOME_PACOExtensionPaCO_Engines_PACO_Container_client.hxx \
+               SALOME_PACOExtensionPaCO_Engines_Parallel_Salome_file_server.hxx \
+               SALOME_PACOExtensionPaCO_Engines_Parallel_Salome_file_client.hxx \
+               SALOME_PACOExtensionPaCO_Engines_Parallel_DSC_server.hxx \
+               SALOME_PACOExtensionPaCO_Engines_Parallel_DSC_client.hxx \
+               SALOME_PACOExtensionPaCO.hxx \
+               SALOME_PACOExtension.hxx \
+               SALOME_ParamPortsPaCO_Ports_Param_Double_Port_server.hxx \
+               SALOME_ParamPortsPaCO_Ports_Param_Double_Port_client.hxx \
+               SALOME_ParamPortsPaCO.hxx \
+               SALOME_ParamPorts.hxx
+
+XML           = SALOME_Component.xml DSC_Engines.xml SALOME_Ports.xml \
+               SALOME_PACOExtension.xml SALOME_ParamPorts.xml
 endif
 
 idldir = $(prefix)/idl/salome
 nodist_idl_DATA = ${XML} ${IDL_PACO} 
-nodist_salomeinclude_HEADERS = ${INCLUDES_PACO} 
+nodist_salomeinclude_HEADERS = ${INCLUDES_PACO}
 
 BUILT_SOURCES = $(IDL_SOURCES) $(PAR) $(PAR_INCLUDES)
 
 SALOME_ComponentPaCO.hxx SALOME_ComponentPaCO.cxx : SALOME_Component.idl SALOME_Component.xml
 SALOME_PortsPaCO.hxx SALOME_PortsPaCO.cxx : SALOME_Ports.idl SALOME_Ports.xml
 DSC_EnginesPaCO.hxx DSC_EnginesPaCO.cxx : DSC_Engines.idl DSC_Engines.xml
+SALOME_PACOExtensionPaCO.hxx SALOME_PACOExtensionPaCO.cxx : SALOME_PACOExtension.idl SALOME_PACOExtension.xml
+SALOME_ParamPortsPaCO.hxx SALOME_ParamPortsPaCO.cxx : SALOME_ParamPorts.idl SALOME_ParamPorts.xml
 
 lib_LTLIBRARIES = libSalomeIDLKernel.la $(PAR_LIB)
 
@@ -243,7 +262,7 @@ if WITH_PACO_PARALLEL
 %PaCO.hxx %PaCO.cxx : %.idl %.xml
        $(OMNIORB_IDL) -p@PACOPATH@/lib/python -bpaco -Wb$(top_srcdir)/idl/$*.xml,$(srcdir):@PACOPATH@/idl $(top_srcdir)/idl/$*.idl
 
-%.hxx : %.idl
+%.hxx: %.idl
        $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) -Wbh=.hxx -Wbs=.cxx $<
 
 endif
index e47f886d031cac89eb998532d292922aff6a2fc6..878d2e6cdfed75a4f866e0646728958886360924 100644 (file)
@@ -407,10 +407,6 @@ module Engines
     string getObjectInfo(in long studyId, in string entry);
   } ;
 
-  interface Parallel_Component : Engines::Component {
-    void send_parallel_proxy_object(in Object proxy_ref);
-  };
-
   //!  A block of binary data used for file transfer. The maximum size of the block is defined on server side.
   typedef sequence<octet> fileBlock;
 
@@ -651,50 +647,6 @@ module Engines
 
     string getRef(in string machine);
   };
-
-  /*! \brief Interface of a Parallel_Salome_file
-    This interface is used by parallel components and containers.
-    It adds methods to enable to choose on which node of the parallel component the file has to 
-    be received.
-  */
-  interface Parallel_Salome_file : Engines::Salome_file {
-
-    /*!
-      Set a number of node for the file. Default is the node 0.
-
-      \param file_name name of the file.
-      \param node_nbr node number where the file is.
-
-      \exception raised if the file doesn't exist.
-    */
-    void setFileNode(in string file_name, in long node_nbr) raises (SALOME::SALOME_Exception);
-
-    /*!
-      Get the number of the node that actually managed the file.
-
-      \param file_name name of managed file.
-
-      \return node number of the file
-
-      \exception raised if the file doesn't exist.
-     */
-    long getFileNode(in string file_name) raises (SALOME::SALOME_Exception);
-
-    /*!
-      This method update the state of file for the Parallel_Salome_file. 
-
-      \param new_file the new state of file.
-     */
-    Engines::Container updateFile(in Engines::file new_file);
-
-    /*!
-      This method is used by the parallel implementation of recvFiles.
-
-      \exception raised if the file cannot be ok.
-     */
-    void recvFiles_node() raises (SALOME::SALOME_Exception);
-
-  };
 };
 
 #endif
index 9f5984394b0500125d129d0b2a0732b6d93293f8..169e7543d990eaeb5270eb1d87a19fda58bb6e3a 100644 (file)
    <Name>ping</Name>
    <Type>distributed</Type>
   </Method>
-  <Method>
-   <Name>create_component_instance</Name>
-   <Type>distributed</Type>
-  </Method>
-  <Method>
-   <Name>load_component_Library</Name>
-   <Type>distributed</Type>
-  </Method>
  </Interface>
  <Interface>
   <Name>Component</Name>
    <Type>distributed</Type>
   </Method>
  </Interface>
- <Interface>
-  <Name>Parallel_Component</Name>
-  <Method>
-   <Name>send_parallel_proxy_object</Name>
-   <Type>distributed</Type>
-  </Method>
- </Interface>
  <Interface>
   <Name>fileTransfer</Name>
  </Interface>
  <Interface>
   <Name>Salome_file</Name>
  </Interface>
- <Interface>
-  <Name>Parallel_Salome_file</Name>
- </Interface>
 </Module>
 </PaCO_Interface_description>
diff --git a/idl/SALOME_PACOExtension.idl b/idl/SALOME_PACOExtension.idl
new file mode 100644 (file)
index 0000000..01cd4f8
--- /dev/null
@@ -0,0 +1,117 @@
+//  Copyright (C) 2007-2009  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SALOME_PACOExtension.idl
+//  Author : André RIBES, EDF
+//  $Header: 
+//
+#ifndef _SALOME_PACOExtension_IDL_
+#define _SALOME_PACOExtension_IDL_
+
+/*! \file SALOME_PACOExtension.idl 
+    \brief Interfaces for Parallel Component and Container using PaCO++
+*/
+
+#include "SALOME_Component.idl"
+#include "DSC_Engines.idl"
+
+module Engines
+{
+  interface Parallel_Component : Engines::Component {
+    void send_parallel_proxy_object(in Object proxy_ref);
+  };
+
+  interface PACO_Container : Engines::Container {
+    // Replicated Method used by the proxy to create
+    // a PACO Component
+    void create_paco_component_node_instance(in string registeredName,
+                                            in long studyId);
+  };
+
+/*--------------------------------------------------------------------------------------------*/
+
+  /*! \brief Interface of a Parallel_DSC component.
+    This interface defines the operations needed to add a paco++ port 
+    into a parallel DSC component.
+  */
+  interface Parallel_DSC : Engines::Superv_Component, Engines::Parallel_Component {
+
+    /*!
+      This operation gives the proxy node of a paco++ port to all the nodes.
+      Only a node of the parallel component is going to add a proxy object 
+      with an internal method.
+
+      \param ref provides proxy port's reference.
+      \param provides_port_name provides port's name.
+
+      \see Engines_ParallelDSC_i::add_parallel_provides_proxy_port
+     */
+    void set_paco_proxy(in Object ref, 
+                       in string provides_port_name,
+                       in Ports::PortProperties port_prop);
+                       
+  };  
+
+  /*! \brief Interface of a Parallel_Salome_file
+    This interface is used by parallel components and containers.
+    It adds methods to enable to choose on which node of the parallel component the file has to 
+    be received.
+  */
+  interface Parallel_Salome_file : Engines::Salome_file {
+
+    /*!
+      Set a number of node for the file. Default is the node 0.
+
+      \param file_name name of the file.
+      \param node_nbr node number where the file is.
+
+      \exception raised if the file doesn't exist.
+    */
+    void setFileNode(in string file_name, in long node_nbr) raises (SALOME::SALOME_Exception);
+
+    /*!
+      Get the number of the node that actually managed the file.
+
+      \param file_name name of managed file.
+
+      \return node number of the file
+
+      \exception raised if the file doesn't exist.
+     */
+    long getFileNode(in string file_name) raises (SALOME::SALOME_Exception);
+
+    /*!
+      This method update the state of file for the Parallel_Salome_file. 
+
+      \param new_file the new state of file.
+     */
+    Engines::Container updateFile(in Engines::file new_file);
+
+    /*!
+      This method is used by the parallel implementation of recvFiles.
+
+      \exception raised if the file cannot be ok.
+     */
+    void recvFiles_node() raises (SALOME::SALOME_Exception);
+  };
+};
+
+#endif
diff --git a/idl/SALOME_PACOExtension.xml b/idl/SALOME_PACOExtension.xml
new file mode 100644 (file)
index 0000000..2c7a059
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+//  Copyright (C) 2007-2009  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SALOME_PACOExtension.xml
+//  Author : Andre RIBES, EDF
+-->
+<PaCO_Interface_description>
+<Module>
+ <Name>Engines</Name>
+ <Interface>
+  <Name>Parallel_Component</Name>
+  <Method>
+   <Name>send_parallel_proxy_object</Name>
+   <Type>distributed</Type>
+  </Method>
+ </Interface>
+ <Interface>
+  <Name>PACO_Container</Name>
+ </Interface>
+ <Interface>
+   <Name>Parallel_DSC</Name>
+   <Method>
+     <Name>set_paco_proxy</Name>
+     <Type>distributed</Type>
+   </Method>
+ </Interface>
+ <Interface>
+  <Name>Parallel_Salome_file</Name>
+ </Interface>
+</Module>
+</PaCO_Interface_description>
+
diff --git a/idl/SALOME_ParamPorts.idl b/idl/SALOME_ParamPorts.idl
new file mode 100644 (file)
index 0000000..9ef4e65
--- /dev/null
@@ -0,0 +1,43 @@
+//  Copyright (C) 2007-2009  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SALOME_ParamPorts.idl
+//  Author : Andre RIBES, EDF
+
+#ifndef _SALOME_ParamPorts_IDL_
+#define _SALOME_ParamPorts_IDL_
+
+#include "SALOME_Ports.idl"
+
+module Ports 
+{
+  /*!  \brief Interface of a port for parametric application
+       This interface defines a Data_Port that sends a vector of
+       double that are distributed along the different processor
+       and returns a vector of double for the results
+  */
+  interface Param_Double_Port : Ports::Data_Port {
+    typedef sequence<double>  seq_double;
+    void put(in Ports::Param_Double_Port::seq_double param_data);
+    void get_results(out Ports::Param_Double_Port::seq_double param_results);
+  };
+};
+#endif
diff --git a/idl/SALOME_ParamPorts.xml b/idl/SALOME_ParamPorts.xml
new file mode 100644 (file)
index 0000000..e6d8a3f
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+//  Copyright (C) 2007-2009  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SALOME_ParamPorts.xml
+//  Author : Andre RIBES, EDF
+-->
+<PaCO_Interface_description>
+<Module>
+ <Name>Ports</Name>
+ <Interface>
+  <Name>Param_Double_Port</Name>
+  <Method>
+   <Name>put</Name>
+   <Type>distributed</Type>
+   <Argument>
+    <Name>param_data</Name>
+    <TypeDis>
+     <Distributed>BasicBC</Distributed>
+    </TypeDis>
+   </Argument>
+  </Method>
+  <Method>
+   <Name>get_results</Name>
+   <Type>distributed</Type>
+   <Argument>
+    <Name>param_results</Name>
+    <TypeDis>
+     <Distributed>GaBro</Distributed>
+    </TypeDis>
+   </Argument>
+  </Method>
+ </Interface>
+</Module>
+</PaCO_Interface_description>
+
index 5763447aae54342c8bf9205fabc1ca5457fda796..2f6b5b3abf772cc11797222ee9db306d3f070f71 100644 (file)
@@ -21,8 +21,7 @@
 //
 //  File   : SALOME_Ports.idl
 //  Author : Andre RIBES, EDF
-//  $Header:
-//
+
 #ifndef _SALOME_PORTS_IDL_
 #define _SALOME_PORTS_IDL_
 
@@ -119,18 +118,6 @@ module Ports {
     //! this operation can be used by a uses port to send me a short 
     void put(in short data);
   };
-
-  /*!  \brief Interface of a port for parametric application
-       This interface defines a Data_Port that sends a vector of
-       double that are distributed along the different processor
-       and returns a vector of double for the results
-  */
-
-  interface Param_Double_Port : Ports::Data_Port {
-    typedef sequence<double>  seq_double;
-    void put(in Ports::Param_Double_Port::seq_double param_data);
-    void get_results(out Ports::Param_Double_Port::seq_double param_results);
-  };
 };
 
 #endif
index bb3e7aa1e631c2d3eaf71b21a6df9a5781f13f81..158637132b317cd3077463d71ce7d1723f3eaf02 100644 (file)
  <Interface>
   <Name>Data_Port</Name>
  </Interface>
- <Interface>
-  <Name>Param_Double_Port</Name>
-  <Method>
-   <Name>put</Name>
-   <Type>distributed</Type>
-   <Argument>
-    <Name>param_data</Name>
-    <TypeDis>
-     <Distributed>BasicBC</Distributed>
-    </TypeDis>
-   </Argument>
-  </Method>
-  <Method>
-   <Name>get_results</Name>
-   <Type>distributed</Type>
-   <Argument>
-    <Name>param_results</Name>
-    <TypeDis>
-     <Distributed>GaBro</Distributed>
-    </TypeDis>
-   </Argument>
-  </Method>
- </Interface>
 </Module>
 </PaCO_Interface_description>
index e83d57d06200a0ff14d4001ea9e65684e46c13fb..ac9273c46028eef812039b94d1c83b4dcd5583f9 100644 (file)
@@ -32,7 +32,7 @@
 #include "DSC_interface.hxx"
 #include "SALOME_ParallelComponent_i.hxx"
 
-#include "DSC_EnginesPaCO_Engines_Parallel_DSC_server.hxx"
+#include "SALOME_PACOExtensionPaCO_Engines_Parallel_DSC_server.hxx"
 #include "SALOME_PortsPaCO.hxx"
 
 class Engines_ParallelDSC_i: 
index 8d638e29636c82e48bc9b934f396dbd128e26f5c..3eba98b21edcc5a95403cdb977ad9bf000497d59 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef _PARAM_DOUBLE_PORT_PROVIDES_HXX_
 #define _PARAM_DOUBLE_PORT_PROVIDES_HXX_
 
-#include "SALOME_PortsPaCO_Ports_Param_Double_Port_server.hxx"
+#include "SALOME_ParamPortsPaCO_Ports_Param_Double_Port_server.hxx"
 
 #include "ParallelDSC_i.hxx"
 #include "PortProperties_i.hxx"
index 745063489e03133fa7712e60819ff12da76faaa4..48bbe04e13181691af38e1a7c1ed9d59e1232e8e 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef _PARAM_DOUBLE_PORT_USES_HXX_
 #define _PARAM_DOUBLE_PORT_USES_HXX_
 
-#include "SALOME_PortsPaCO_Ports_Param_Double_Port_client.hxx"
+#include "SALOME_ParamPortsPaCO_Ports_Param_Double_Port_client.hxx"
 
 #include "ParallelDSC_i.hxx"
 #include "PortProperties_i.hxx"
index 62d705aacba7d5bde86a87863891299dfa05a4b5..dc20c67ab2a8378950b28d4779c917bd4163bea0 100644 (file)
@@ -34,6 +34,7 @@ include $(top_srcdir)/salome_adm/unix/make_common_starter.am
 salomeinclude_HEADERS = SALOME_ParallelComponent_i.hxx \
                        SALOME_ParallelContainer_i.hxx \
                        SALOME_ParallelContainerProxy_i.hxx \
+                       SALOME_ParallelGlobalProcessVar_i.hxx \
                        Parallel_Salome_file_i.hxx
 
 #
@@ -54,8 +55,10 @@ COMMON_CPPFLAGS= -I$(top_srcdir)/src/Container \
                 -I$(top_builddir)/salome_adm/unix \
                 -I$(top_builddir)/idl \
                 -I$(top_srcdir)/src/SALOMETraceCollector \
+                @PYTHON_INCLUDES@ \
                 @CORBA_CXXFLAGS@ \
                 @CORBA_INCLUDES@ \
+                @MPI_INCLUDES@ \
                 @PACO_INCLUDES@
 
 # This local variable defines the list of dependant libraries common to all target in this package.
@@ -64,7 +67,8 @@ COMMON_LIBS = $(top_builddir)/src/Container/libSalomeContainer.la \
              $(top_builddir)/idl/libSalomeParallelIDLKernel.la \
              $(top_builddir)/idl/libSalomeIDLKernel.la \
              @CORBA_LIBS@ \
-             @PACO_LIBS@
+             @PACO_LIBS@ \
+             $(PYTHON_LIBS)
 
 #
 # ===============================================================
@@ -77,7 +81,8 @@ libSalomeParallelContainer_la_SOURCES  = SALOME_ParallelComponent_i.cxx \
                                         SALOME_ParallelContainer_i.cxx \
                                         SALOME_ParallelContainerProxy_i.cxx \
                                         $(top_srcdir)/src/Container/Salome_file_i.cxx \
-                                        Parallel_Salome_file_i.cxx
+                                        Parallel_Salome_file_i.cxx \
+                                        SALOME_ParallelGlobalProcessVar_i.cxx
 
 libSalomeParallelContainer_la_CXXFLAGS = $(COMMON_CPPFLAGS)
 
index 07ccd09924d399082429769a646cf5eb5f980590..ee7ec3f0449f5a365e20c0f9634cd5aed692f03e 100644 (file)
@@ -32,7 +32,7 @@
 #include <map>
 #include <cstdio>
 
-#include "SALOME_ComponentPaCO_Engines_Parallel_Salome_file_server.hxx"
+#include "SALOME_PACOExtensionPaCO_Engines_Parallel_Salome_file_server.hxx"
 #include "Salome_file_i.hxx"
 
 class CONTAINER_EXPORT Parallel_Salome_file_i:
index 49cbbfaa015fbb531e1418a3fc4e23934aa528af..11c0e83851cb53e8658a209526a7ac7175cc48a7 100644 (file)
@@ -38,7 +38,7 @@
 #include <map>
 #include <SALOMEconfig.h>
 
-#include "SALOME_ComponentPaCO_Engines_Parallel_Component_server.hxx"
+#include "SALOME_PACOExtensionPaCO_Engines_Parallel_Component_server.hxx"
 
 #include "NOTIFICATION.hxx"
 #include "RegistryConnexion.hxx"
index f00184b644daad4a140b6b4bb7bc0effe4123b3d..683a6f660e703c6d027c6fd1df136e64ba1d2f9c 100644 (file)
@@ -101,7 +101,9 @@ int main(int argc, char* argv[])
 
     Container_proxy_impl_final * proxy = 
       new Container_proxy_impl_final(orb,
-                                    new paco_omni_fabrique());
+                                    new paco_omni_fabrique(),
+                                    root_poa,
+                                    containerName);
     // PaCO++ code
     paco_fabrique_manager* pfm = paco_getFabriqueManager();
     pfm->register_com("dummy", new paco_dummy_fabrique());
index 73c9b333172de62e98bdd1b11d603df80da14c96..2ed477903d803967fe6b5c8314bb4eb9f9a8eb9e 100644 (file)
@@ -155,8 +155,10 @@ int main(int argc, char* argv[])
 //      new Engines::Container_proxy_impl(orb, 
 //                                     new paco_omni_fabrique());
     Container_proxy_impl_final * proxy = 
-      new Container_proxy_impl_final(orb, 
-                                    new paco_omni_fabrique());
+      new Container_proxy_impl_final(orb,
+                                    new paco_omni_fabrique(),
+                                    root_poa,
+                                    containerName);
 
     // PaCO++ code
     paco_fabrique_manager* pfm = paco_getFabriqueManager();
index dfdcab72d41b82c36a22e71fea947808fabb4a2c..90b61996b11078e570c26a5db67ad7f71915d7c8 100644 (file)
 //  SALOME_ParallelContainerProxy : implementation of container and engine for Parallel Kernel
 //  File   : SALOME_ParallelContainerProxy_i.cxx
 //  Author : André RIBES, EDF
-//
+
 #include "SALOME_ParallelContainerProxy_i.hxx"
 
 Container_proxy_impl_final::Container_proxy_impl_final(CORBA::ORB_ptr orb, 
                                                       paco_fabrique_thread * fab_thread, 
+                                                      PortableServer::POA_ptr poa,
+                                                      std::string containerName,
                                                       bool is_a_return_proxy) :
+  Engines::PACO_Container_proxy_impl(orb, fab_thread, is_a_return_proxy),
   Engines::Container_proxy_impl(orb, fab_thread, is_a_return_proxy),
   InterfaceManager_impl(orb, fab_thread, is_a_return_proxy)
-{}
+{
+  _numInstance = 0;
+  _containerName = containerName;
+  _poa = PortableServer::POA::_duplicate(poa);
+
+  // Add CORBA object to the poa
+  _id = _poa->activate_object(this);
+  this->_remove_ref();
+
+  // Init SALOME Naming Service
+  _NS = new SALOME_NamingService();
+  _NS->init_orb(_orb);
+}
 
 Container_proxy_impl_final:: ~Container_proxy_impl_final() {}
 
 void
 Container_proxy_impl_final::Shutdown()
 {
+  // We call shutdown in each node
+  for (CORBA::ULong i = 0; i < _infos.nodes.length(); i++)
+  {
+    MESSAGE("Shutdown work node : " << i);
+    CORBA::Object_var object = _orb->string_to_object(_infos.nodes[i]);
+    Engines::Container_var node = Engines::Container::_narrow(object);
+    if (!CORBA::is_nil(node))
+    {
+      try 
+      {
+       node->Shutdown();
+       MESSAGE("Shutdown done node : " << i);
+      }
+      catch (...)
+      {
+       INFOS("Exception catch during Shutdown of node : " << i);
+      }
+    }
+    else
+    {
+      INFOS("Cannot shutdown node " << i << " ref is nil !");
+    }
+  }
+
   INFOS("Shutdown Parallel Proxy");
   if(!CORBA::is_nil(_orb))
     _orb->shutdown(0);
 }
 
+// On intercepte cette méthode pour pouvoir ensuite
+// déterminer si on doit créer une instance sequentielle
+// ou parallèle d'un composant dans la méthode create_component_instance
+CORBA::Boolean 
+Container_proxy_impl_final::load_component_Library(const char* componentName)
+{
+  MESSAGE("Begin of load_component_Library on proxy : " << componentName)
+  std::string aCompName = componentName;
+
+  if (_libtype_map.count(aCompName) == 0)
+  {
+    _numInstanceMutex.lock(); // lock to be alone
+
+    // Default lib is seq
+    _libtype_map[aCompName] = "seq";
+
+    // --- try dlopen C++ component
+    // If is not a C++ or failed then is maybe 
+    // a seq component...
+
+    MESSAGE("Try to load C++ component");
+#ifndef WIN32
+    std::string impl_name = string ("lib") + aCompName + string("Engine.so");
+#else
+    std::string impl_name = aCompName + string("Engine.dll");
+#endif
+    void* handle;
+#ifndef WIN32
+    handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ;
+#else
+    handle = dlopen( impl_name.c_str() , 0 ) ;
+#endif
+    if ( handle )
+    {
+      _library_map[impl_name] = handle;
+      MESSAGE("Library " << impl_name << " loaded");
+
+      //Test if lib could contain a parallel component
+
+      std::string paco_test_fct_signature("isAPACO_Component");
+      PACO_TEST_FUNCTION paco_test_fct = NULL;
+#ifndef WIN32
+      paco_test_fct = (PACO_TEST_FUNCTION)dlsym(handle, paco_test_fct_signature.c_str());
+#else
+      paco_test_fct = (PACO_TEST_FUNCTION)GetProcAddress((HINSTANCE)handle, paco_test_fct_signature.c_str());
+#endif
+      if (!paco_test_fct)
+      {
+       // PaCO Component found
+       MESSAGE("PACO LIB FOUND");
+       _libtype_map[aCompName] = "par";
+       _parlibfct_map[aCompName] = paco_test_fct;
+      }
+    }
+    _numInstanceMutex.unlock();
+  }
+
+  // Call load_component_Library in each node
+  CORBA::Boolean ret = true;
+  for (CORBA::ULong i = 0; i < _infos.nodes.length(); i++)
+  {
+    MESSAGE("Call load_component_Library work node : " << i);
+    CORBA::Object_var object = _orb->string_to_object(_infos.nodes[i]);
+    Engines::Container_var node = Engines::Container::_narrow(object);
+    if (!CORBA::is_nil(node))
+    {
+      try 
+      {
+       node->load_component_Library(componentName);
+       MESSAGE("Call load_component_Library done node : " << i);
+      }
+      catch (...)
+      {
+       INFOS("Exception catch during load_component_Library of node : " << i);
+       ret = false;
+      }
+    }
+    else
+    {
+      INFOS("Cannot call load_component_Library node " << i << " ref is nil !");
+      ret = false;
+    }
+  }
+
+  // If ret is false -> lib is not loaded !
+  _libtype_map.erase(aCompName);
+  return ret;
+}
+
+// Il y a deux cas :
+// Composant sequentiel -> on le créer sur le noeud 0 (on pourrait faire une répartition de charge)
+// Composant parallèle -> création du proxy ici puis appel de la création de chaque objet participant
+// au composant parallèle
+Engines::Component_ptr 
+Container_proxy_impl_final::create_component_instance(const char* componentName, ::CORBA::Long studyId)
+{
+  std::string aCompName = componentName;
+  if (_libtype_map.count(aCompName) == 0)
+  {
+    // Component is not loaded !
+    INFOS("Proxy: component is not loaded !");
+    return Engines::Component::_nil();
+  }
+
+  // If it is a sequential component
+  if (_libtype_map[aCompName] == "seq")
+    return Engines::Container_proxy_impl::create_component_instance(componentName, studyId);
+
+  // Test if the component inside the parallel lib
+  // is parallel or sequential
+  bool parallel_component = (_parlibfct_map[aCompName]) (componentName);
+  if (!parallel_component)
+    return Engines::Container_proxy_impl::create_component_instance(componentName, studyId);
+
+  // Parallel Component !
+  Engines::Component_var component_proxy = Engines::Component::_nil();
+
+  // On commence par créer le proxy
+#ifndef WIN32
+  std::string impl_name = string ("lib") + aCompName + string("Engine.so");
+#else
+  std::string impl_name = aCompName + string("Engine.dll");
+#endif
+  void* handle = _library_map[impl_name];
+  std::string factory_name = aCompName + std::string("EngineProxy_factory");
+
+  MESSAGE("Creating component proxy : " << factory_name);
+  FACTORY_FUNCTION component_proxy_factory = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
+
+  if (!component_proxy_factory)
+  {
+    INFOS("Can't resolve symbol: " + factory_name);
+#ifndef WIN32
+    INFOS("dlerror() result is : " << dlerror());
+#endif
+    return 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 = aCompName + "_inst_" + aNumI ;
+    string component_registerName = _containerName + "/" + instanceName;
+
+    // --- Instanciate required CORBA object
+    PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
+    id = (component_proxy_factory) (_orb, 
+                                   new paco_omni_fabrique(), 
+                                   _poa, 
+                                   _id, 
+                                   instanceName.c_str(), 
+                                   _parallel_object_topology.total) ;
+
+    // --- get reference & servant from id
+    CORBA::Object_var obj = _poa->id_to_reference(*id);
+    component_proxy = Engines::Component::_narrow(obj) ;
+
+    _cntInstances_map[impl_name] += 1;
+
+    // --- register the engine under the name
+    //     containerName(.dir)/instanceName(.object)
+    _NS->Register(component_proxy , component_registerName.c_str()) ;
+    MESSAGE(component_registerName.c_str() << " bound" ) ;
+  }
+  catch (...)
+  {
+    INFOS( "Exception catched in Proxy creation" );
+    return Engines::Component::_nil();
+  }
+
+  return component_proxy;
+}
index ef6e66367ea647f4fe415a67a2c6f697224d769c..bef0b12b7c0d954e981c159852db4cbe1cbb3341 100644 (file)
 //  SALOME_ParallelContainerProxy : implementation of container and engine for Parallel Kernel
 //  File   : SALOME_ParallelContainerProxy_i.hxx
 //  Author : André RIBES, EDF
-//
+
 #ifndef _SALOME_PARALLEL_CONTAINER_PROXY_I_HXX_
 #define _SALOME_PARALLEL_CONTAINER_PROXY_I_HXX_
 
 #include "utilities.h"
-#include "SALOME_ComponentPaCO_Engines_Container_server.hxx"
+#include "SALOME_PACOExtensionPaCO_Engines_PACO_Container_server.hxx"
+#include "SALOME_ParallelGlobalProcessVar_i.hxx"
+#include "SALOME_NamingService.hxx"
+#include <map>
+#include <dlfcn.h>
+#include <paco_omni.h>
 
 class Container_proxy_impl_final :
-  public Engines::Container_proxy_impl
+  virtual public Engines::PACO_Container_proxy_impl,
+  virtual public ParallelGlobalProcessVar_i
 {
   public:
     Container_proxy_impl_final(CORBA::ORB_ptr orb, 
-                              paco_fabrique_thread * fab_thread, 
+                              paco_fabrique_thread * fab_thread,
+                              PortableServer::POA_ptr poa,
+                              std::string containerName,
                               bool is_a_return_proxy = false);
 
     virtual ~Container_proxy_impl_final();
 
     virtual void Shutdown();
+
+    virtual ::CORBA::Boolean load_component_Library(const char* componentName);
+    virtual Engines::Component_ptr create_component_instance(const char* componentName, ::CORBA::Long studyId);
+
+  private:
+    std::map<std::string, std::string> _libtype_map; // libname -> libtype (seq ou par)
+    typedef bool (*PACO_TEST_FUNCTION) (const char *);
+    typedef PortableServer::ObjectId * (*FACTORY_FUNCTION) (CORBA::ORB_ptr,
+                                                           paco_fabrique_thread *,
+                                                           PortableServer::POA_ptr,
+                                                           PortableServer::ObjectId *, 
+                                                           const char *,
+                                                           int);
+    std::map<std::string, PACO_TEST_FUNCTION> _parlibfct_map;
+    int _numInstance;
+    std::string _containerName;
+    PortableServer::POA_var _poa;
+    PortableServer::ObjectId * _id;
+    SALOME_NamingService *_NS;
 };
 
 #endif
index 2f45c86580674e212128c51b50eecaa998e557f1..af29dbc614601fd57a1d3b4de1e55430849dee32 100644 (file)
 //
 //  SALOME_ParallelContainer : implementation of container and engine for ParallelKernel
 //  File   : SALOME_ParallelContainer_i.cxx
-//  Author : Andr� RIBES, EDF
-//  Author : Paul RASCLE, EDF - MARC TAJCHMAN, CEA 
-//
-#include <SALOMEconfig.h>
-#ifndef WIN32
-#else
-#include <SALOME_Component.hxx>
-#endif
-#include "SALOME_ParallelContainer_i.hxx"
+//  Author : André RIBES, EDF
 
+#include "SALOME_ParallelContainer_i.hxx"
 #include "SALOME_Component_i.hxx"
-
 #include "SALOME_FileRef_i.hxx"
 #include "SALOME_FileTransfer_i.hxx"
 #include "SALOME_NamingService.hxx"
 #include "OpUtil.hxx"
+#include "utilities.h"
+#include "Basics_Utils.hxx"
 
 #include <string.h>
 #include <stdio.h>
 #ifndef WIN32
+#include <sys/time.h>
 #include <dlfcn.h>
 #include <unistd.h>
 #else
-#include "../../adm/win32/SALOME_WNT.hxx"
 #include <signal.h>
 #include <process.h>
+#include <direct.h>
 int SIGUSR1 = 1000;
 #endif
 
 #include <paco_omni.h>
-#include "utilities.h"
-#include "Basics_Utils.hxx"
+
+#include <Python.h>
+#include "Container_init_python.hxx"
+
 using namespace std;
 
 bool _Sleeping = false ;
 
-// Containers with name FactoryServer are started via rsh in LifeCycleCORBA
-// Other Containers are started via start_impl of FactoryServer
-
 extern "C" {void ActSigIntHandler() ; }
 #ifndef WIN32
 extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; }
@@ -67,31 +61,14 @@ extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; }
 extern "C" {void SigIntHandler( int ) ; }
 #endif
 
-
-map<std::string, int> Engines_Parallel_Container_i::_cntInstances_map;
-map<std::string, void *> Engines_Parallel_Container_i::_library_map;
-map<std::string, void *> Engines_Parallel_Container_i::_toRemove_map;
-omni_mutex Engines_Parallel_Container_i::_numInstanceMutex ;
-
-//=============================================================================
-/*! 
- *  Default constructor, not for use
+/*! \class Engines_Parallel_Container_i
+ *  \brief C++ implementation of Engines::Container interface for parallel
+ *  container implemented with PaCO++
  */
-//=============================================================================
-
-Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb, 
-                                                           char * ior, 
-                                                           int rank) : 
-  InterfaceParallel_impl(orb,ior,rank), 
-  Engines::Container_serv(orb,ior,rank),
-  Engines::Container_base_serv(orb,ior,rank),
-  _numInstance(0)
-{
-}
 
 //=============================================================================
 /*! 
- *  Construtor to use
+ *  Construtor
  */
 //=============================================================================
 
@@ -101,32 +78,52 @@ Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb,
                                                            PortableServer::POA_ptr poa,
                                                            char *containerName ,
                                                            int argc , char* argv[],
-                                                           bool activAndRegist,
                                                            bool isServantAloneInProcess
                                                           ) :
   InterfaceParallel_impl(orb,ior,rank), 
+  Engines::PACO_Container_serv(orb,ior,rank),
+  Engines::PACO_Container_base_serv(orb,ior,rank),
   Engines::Container_serv(orb,ior,rank),
   Engines::Container_base_serv(orb,ior,rank),
   _numInstance(0),_isServantAloneInProcess(isServantAloneInProcess)
 {
-  _pid = (long)getpid();
-
-  if(activAndRegist)
-    ActSigIntHandler() ;
-
+  // Members init
+  _pid = getpid();
   _argc = argc ;
   _argv = argv ;
+  _hostname = Kernel_Utils::GetHostname();
+  _orb = CORBA::ORB::_duplicate(orb);
+  _poa = PortableServer::POA::_duplicate(poa);
 
-  string hostname = Kernel_Utils::GetHostname();
+  // Add CORBA object to the poa
+  _id = _poa->activate_object(this);
+  this->_remove_ref();
+  CORBA::Object_var container_node = _poa->id_to_reference(*_id);
 
-  _orb = CORBA::ORB::_duplicate(orb) ;
-  _poa = PortableServer::POA::_duplicate(poa) ;
+  // Adding this servant to SALOME
   _NS = new SALOME_NamingService();
-  _NS->init_orb( CORBA::ORB::_duplicate(_orb) );
-  _containerName = _NS->BuildContainerNameForNS(containerName, hostname.c_str());
-
+  _NS->init_orb(_orb);
+  _containerName = _NS->BuildContainerNameForNS(containerName, _hostname.c_str());
+  _NS->Register(container_node, _containerName.c_str());
+
+  // Init Python container part
+  CORBA::String_var sior =  _orb->object_to_string(container_node);
+  std::string myCommand="pyCont = SALOME_Container.SALOME_Container_i('";
+  myCommand += _containerName + "','";
+  myCommand += sior;
+  myCommand += "')\n";
+  Py_ACQUIRE_NEW_THREAD;
+  PyRun_SimpleString("import SALOME_Container\n");
+  PyRun_SimpleString((char*)myCommand.c_str());
+  Py_RELEASE_NEW_THREAD;
+
+  // Init FileTransfer service
   fileTransfer_i* aFileTransfer = new fileTransfer_i();
-  _fileTransfer = Engines::fileTransfer::_narrow(aFileTransfer->_this());
+  _fileTransfer = aFileTransfer->_this();
+  aFileTransfer->_remove_ref();
+
+  // Some signal handlers
+  ActSigIntHandler();
 }
 
 //=============================================================================
@@ -138,10 +135,14 @@ Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb,
 Engines_Parallel_Container_i::~Engines_Parallel_Container_i()
 {
   MESSAGE("Container_i::~Container_i()");
-  delete _id;
+  if (_id)
+    delete _id;
+  if(_NS)
+    delete _NS;
 }
 
 //=============================================================================
+//! Get container name
 /*! 
  *  CORBA attribute: Container name (see constructor)
  */
@@ -153,6 +154,42 @@ char* Engines_Parallel_Container_i::name()
 }
 
 //=============================================================================
+//! Get container working directory
+/*! 
+ *  CORBA attribute: Container working directory 
+ */
+//=============================================================================
+
+char* 
+Engines_Parallel_Container_i::workingdir()
+{
+  char wd[256];
+  getcwd (wd,256);
+  return CORBA::string_dup(wd) ;
+}
+
+//=============================================================================
+//! Get container log file name
+/*! 
+ *  CORBA attribute: Container log file name
+ */
+//=============================================================================
+
+char* 
+Engines_Parallel_Container_i::logfilename()
+{
+  return CORBA::string_dup(_logfilename.c_str()) ;
+}
+
+//! Set container log file name
+void 
+Engines_Parallel_Container_i::logfilename(const char* name)
+{
+  _logfilename=name;
+}
+
+//=============================================================================
+//! Get container host name
 /*! 
  *  CORBA method: Get the hostName of the Container (without domain extensions)
  */
@@ -160,12 +197,12 @@ char* Engines_Parallel_Container_i::name()
 
 char* Engines_Parallel_Container_i::getHostName()
 {
-  string s = Kernel_Utils::GetHostname();
-  MESSAGE("Engines_Parallel_Container_i::getHostName " << s);
-  return CORBA::string_dup(s.c_str()) ;
+  MESSAGE("Warning: getHostName of a parallel container returns the hostname of the first servant node");
+  return CORBA::string_dup(_hostname.c_str()) ;
 }
 
 //=============================================================================
+//! Get container PID
 /*! 
  *  CORBA method: Get the PID (process identification) of the Container
  */
@@ -173,10 +210,12 @@ char* Engines_Parallel_Container_i::getHostName()
 
 CORBA::Long Engines_Parallel_Container_i::getPID()
 {
-  return (CORBA::Long)getpid();
+  MESSAGE("Warning: getPID of a parallel container returns the PID of the first servant node");
+  return _pid;
 }
 
 //=============================================================================
+//! Ping the servant to check it is still alive
 /*! 
  *  CORBA method: check if servant is still alive
  */
@@ -184,10 +223,11 @@ CORBA::Long Engines_Parallel_Container_i::getPID()
 
 void Engines_Parallel_Container_i::ping()
 {
-  MESSAGE("Engines_Parallel_Container_i::ping() pid "<< getpid());
+  MESSAGE("Engines_Parallel_Container_i::ping() my pid is "<< _pid);
 }
 
 //=============================================================================
+//! Shutdown the container
 /*! 
  *  CORBA method, oneway: Server shutdown. 
  *  - Container name removed from naming service,
@@ -199,20 +239,40 @@ void Engines_Parallel_Container_i::ping()
 void Engines_Parallel_Container_i::Shutdown()
 {
   MESSAGE("Engines_Parallel_Container_i::Shutdown()");
+  /* For each component contained in this container
+  * tell it to self-destroy
+  */
+  std::map<std::string, Engines::Component_var>::iterator itm;
+  for (itm = _listInstances_map.begin(); itm != _listInstances_map.end(); itm++)
+  {
+    try
+    {
+      itm->second->destroy();
+    }
+    catch(const CORBA::Exception& e)
+    {
+      // ignore this entry and continue
+    }
+    catch(...)
+    {
+      // ignore this entry and continue
+    }
+  }
+
   _NS->Destroy_FullDirectory(_containerName.c_str());
-  //_remove_ref();
-  //_poa->deactivate_object(*_id);
+  _NS->Destroy_Name(_containerName.c_str());
+
   if(_isServantAloneInProcess)
   {
     MESSAGE("Effective Shutdown of container Begins...");
-    LocalTraceBufferPool* bp1 = LocalTraceBufferPool::instance();
-    bp1->deleteInstance(bp1);
-    _orb->shutdown(0);
+    if(!CORBA::is_nil(_orb))
+      _orb->shutdown(0);
   }
 }
 
 
 //=============================================================================
+//! load a new component class
 /*! 
  *  CORBA method: load a new component class (Python or C++ implementation)
  *  \param componentName like COMPONENT
@@ -225,54 +285,86 @@ void Engines_Parallel_Container_i::Shutdown()
 bool
 Engines_Parallel_Container_i::load_component_Library(const char* componentName)
 {
+  MESSAGE("Begin of load_component_Library : " << componentName)
   bool ret = false;
-  string aCompName = componentName;
-  // --- try dlopen C++ component
-
+  std::string aCompName = componentName;
 #ifndef WIN32
   string impl_name = string ("lib") + aCompName + string("Engine.so");
 #else
   string impl_name = aCompName + string("Engine.dll");
 #endif
 
-  SCRUTE(impl_name);
-
   _numInstanceMutex.lock(); // lock to be alone 
-  if (_toRemove_map[impl_name]) _toRemove_map.erase(impl_name);
-  if (_library_map[impl_name])
+
+  // Check if already loaded or imported in the container
+  if (_toRemove_map.count(impl_name) != 0) _toRemove_map.erase(impl_name);
+  if (_library_map.count(impl_name) != 0)
   {
     MESSAGE("Library " << impl_name << " already loaded");
-    _numInstanceMutex.unlock();
+    ret = true;
+  }
+  if (_library_map.count(aCompName) != 0)
+  {
+    MESSAGE("Python component already imported");
     ret = true;
   }
 
-  void* handle;
+  // --- try dlopen C++ component
+  if (!ret)
+  {
+    MESSAGE("Try to load C++ component");
+    void* handle;
 #ifndef WIN32
-  handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ;
+    handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ;
 #else
-  handle = dlopen( impl_name.c_str() , 0 ) ;
+    handle = dlopen( impl_name.c_str() , 0 ) ;
 #endif
-  if ( handle )
-  {
-    _library_map[impl_name] = handle;
-    _numInstanceMutex.unlock();
-    ret = true;
+    if ( handle )
+    {
+      _library_map[impl_name] = handle;
+      MESSAGE("Library " << impl_name << " loaded");
+      ret = true;
+    }
+    else
+    {
+      std::cerr << "Can't load shared library : " << impl_name << std::endl;
+      std::cerr << "error of dlopen: " << dlerror() << std::endl;
+    }
   }
-  else
+
+  // --- try import Python component
+  if (!ret)
   {
-    cerr << "Can't load shared library : " << impl_name << endl;
-    cerr << "error dlopen: " << dlerror() << endl;
-    _numInstanceMutex.unlock();
-    ret = false;
+    MESSAGE("Try to import Python component "<<componentName);
+    Py_ACQUIRE_NEW_THREAD;
+    PyObject *mainmod = PyImport_AddModule("__main__");
+    PyObject *globals = PyModule_GetDict(mainmod);
+    PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
+    PyObject *result = PyObject_CallMethod(pyCont,
+                                          (char*)"import_component",
+                                          (char*)"s",componentName);
+    int ret_p= PyInt_AsLong(result);
+    Py_XDECREF(result);
+    Py_RELEASE_NEW_THREAD;
+
+    if (ret_p) // import possible: Python component
+    {
+      _library_map[aCompName] = (void *)pyCont; // any non O value OK
+      MESSAGE("import Python: " << aCompName <<" OK");
+      ret = true;
+    }
+    else
+    {
+      std::cerr << "Error in importing Python component : " << aCompName << std::endl;
+    }
   }
 
-  // To be sure that all the nodes of the component as loaded the library
-  _my_com->paco_barrier();
-
+  _numInstanceMutex.unlock();
   return ret;
 }
 
 //=============================================================================
+//! Create a new component instance
 /*! 
  *  CORBA method: Creates a new servant instance of a component.
  *  The servant registers itself to naming service and Registry.
@@ -288,7 +380,7 @@ Engines::Component_ptr
 Engines_Parallel_Container_i::create_component_instance(const char*genericRegisterName,
                                                        CORBA::Long studyId)
 {
-  cerr << "----------------- create_component_instance node : " << getMyRank() << endl;
+  MESSAGE("Begin of create_component_instance in node : " << getMyRank());
 
   if (studyId < 0)
   {
@@ -296,52 +388,38 @@ Engines_Parallel_Container_i::create_component_instance(const char*genericRegist
     return Engines::Component::_nil() ;
   }
 
-  Engines::Component_var iobject = Engines::Component::_nil() ;
-
-  // is it a parallel component ?
-  bool parallel = false;
-  string aCompName = genericRegisterName;
-  int par = aCompName.find("@PARALLEL@");
-  if (par>0) {
-    parallel = true;
-    aCompName = aCompName.substr(0,par);
-  }
-
-  //--- try C++
+  std::string aCompName = genericRegisterName;
 #ifndef WIN32
   string impl_name = string ("lib") + aCompName +string("Engine.so");
 #else
   string impl_name = aCompName +string("Engine.dll");
 #endif
-  void* handle = _library_map[impl_name];
 
-  if ( !handle )
+  // Test if the component lib is loaded
+  std::string type_of_lib("Not Loaded");
+  void* handle = _library_map[impl_name];
+  if (handle)
+    type_of_lib = "cpp";
+  if (_library_map.count(aCompName) != 0 and !handle)
+    type_of_lib = "python";
+  
+  if (type_of_lib == "Not Loaded")
   {
-    cerr << "shared library " << impl_name <<"must be loaded before instance" << endl;;
-    return Engines::Component::_nil() ;
+    std::cerr << "Component library is not loaded or imported ! lib was : " << aCompName << std::endl;
+    return Engines::Component::_nil();
   }
-  else
-  {
-    if (parallel) {
-      // Sequential component case
-      // Component parallel proxy created on node 0
-      iobject = createParallelInstance(aCompName,
-                                      handle,
-                                      studyId);
 
-    }
-    else {
-      // Sequential component case
-      iobject = createInstance(aCompName,
-                              handle,
-                              studyId);
-    }
+  Engines::Component_var iobject = Engines::Component::_nil();
+  if (type_of_lib == "cpp")
+    iobject = createCPPInstance(aCompName, handle, studyId);
+  else
+    iobject = createPythonInstance(aCompName, studyId);
 
-    return iobject._retn();
-  }
+  return iobject._retn();
 }
 
 //=============================================================================
+//! Find an existing (in the container) component instance
 /*! 
  *  CORBA method: Finds a servant instance of a component
  *  \param registeredName  Name of the component in Registry or Name Service,
@@ -375,6 +453,7 @@ Engines::Component_ptr Engines_Parallel_Container_i::find_component_instance( co
 }
 
 //=============================================================================
+//! Find or create a new component instance
 /*! 
  *  CORBA method: find or create an instance of the component (servant),
  *  load a new component class (dynamic library) if required,
@@ -391,15 +470,15 @@ Engines::Component_ptr Engines_Parallel_Container_i::find_component_instance( co
 Engines::Component_ptr Engines_Parallel_Container_i::load_impl( const char* genericRegisterName,
                                                                const char* componentName )
 {
-  string impl_name = string ("lib") + genericRegisterName +string("Engine.so");
-  Engines::Component_var iobject = Engines::Component::_nil() ;
+  Engines::Component_var iobject = Engines::Component::_nil();
   if (load_component_Library(genericRegisterName))
-    iobject = find_or_create_instance(genericRegisterName, impl_name);
+    iobject = find_or_create_instance(genericRegisterName);
   return iobject._retn();
 }
 
 
 //=============================================================================
+//! Remove the component instance from container
 /*! 
  *  CORBA method: Stops the component servant, and deletes all related objects
  *  \param component_i     Component to be removed
@@ -408,15 +487,26 @@ Engines::Component_ptr Engines_Parallel_Container_i::load_impl( const char* gene
 
 void Engines_Parallel_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() ;
-  _NS->Destroy_Name(instanceName.c_str());
+  ASSERT(!CORBA::is_nil(component_i));
+  string instanceName = component_i->instanceName();
+  _numInstanceMutex.lock() ; // lock to be alone (stl container write)
+  // Test if the component is in this container
+  std::map<std::string, Engines::Component_var>::iterator itm;
+  itm = _listInstances_map.find(instanceName);
+  if (itm != _listInstances_map.end())
+  {
+    MESSAGE("Unloading component " << instanceName);
+    _listInstances_map.erase(instanceName);
+    component_i->destroy() ;
+    _NS->Destroy_Name(instanceName.c_str());
+  }
+  else
+    std::cerr << "WARNING !!!! component instance was not in this container !!!" << std::endl;
+  _numInstanceMutex.unlock() ;
 }
 
 //=============================================================================
+//! Unload component libraries from the container
 /*! 
  *  CORBA method: Discharges unused libraries from the container.
  */
@@ -424,27 +514,31 @@ void Engines_Parallel_Container_i::remove_impl(Engines::Component_ptr component_
 
 void Engines_Parallel_Container_i::finalize_removal()
 {
-  MESSAGE("finalize unload : dlclose");
-  _numInstanceMutex.lock(); // lock to be alone
+  MESSAGE("Finalize removal : dlclose");
+  MESSAGE("WARNING FINALIZE DOES CURRENTLY NOTHING !!!");
+
   // (see decInstanceCnt, load_component_Library)
-  map<string, void *>::iterator ith;
-  for (ith = _toRemove_map.begin(); ith != _toRemove_map.end(); ith++)
-  {
-    void *handle = (*ith).second;
-    string impl_name= (*ith).first;
-    if (handle)
-    {
-      SCRUTE(handle);
-      SCRUTE(impl_name);
-      //         dlclose(handle);                // SALOME unstable after ...
-      //         _library_map.erase(impl_name);
-    }
-  }
+  //map<string, void *>::iterator ith;
+  //for (ith = _toRemove_map.begin(); ith != _toRemove_map.end(); ith++)
+  //{
+  //  void *handle = (*ith).second;
+  //  string impl_name= (*ith).first;
+  //  if (handle)
+  //  {
+  //    SCRUTE(handle);
+  //    SCRUTE(impl_name);
+  //    dlclose(handle);                // SALOME unstable after ...
+  //    _library_map.erase(impl_name);
+  //  }
+  //}
+
+  _numInstanceMutex.lock(); // lock to be alone
   _toRemove_map.clear();
   _numInstanceMutex.unlock();
 }
 
 //=============================================================================
+//! Kill the container
 /*! 
  *  CORBA method: Kill the container process with exit(0).
  *  To remove :  never returns !
@@ -453,9 +547,9 @@ void Engines_Parallel_Container_i::finalize_removal()
 
 bool Engines_Parallel_Container_i::Kill_impl()
 {
-  MESSAGE("Engines_Parallel_Container_i::Kill() pid "<< getpid() << " containerName "
-         << _containerName.c_str() << " machineName "
-         << Kernel_Utils::GetHostname().c_str());
+  MESSAGE("Engines_Parallel_Container_i::Kill() my pid is "<< _pid 
+         << " my containerName is " << _containerName.c_str() 
+         << " my machineName is " << _hostname.c_str());
   INFOS("===============================================================");
   INFOS("= REMOVE calls to Kill_impl in C++ container                  =");
   INFOS("===============================================================");
@@ -464,7 +558,96 @@ bool Engines_Parallel_Container_i::Kill_impl()
   return false;
 }
 
+//=============================================================================
+//! Get or create a file reference object associated to a local file (to transfer it)
+/*! 
+ *  CORBA method: get or create a fileRef object associated to a local file
+ *  (a file on the computer on which runs the container server), which stores
+ *  a list of (machine, localFileName) corresponding to copies already done.
+ * 
+ *  \param  origFileName absolute path for a local file to copy on other
+ *          computers
+ *  \return a fileRef object associated to the file.
+ */
+//=============================================================================
+
+Engines::fileRef_ptr
+Engines_Parallel_Container_i::createFileRef(const char* origFileName)
+{
+  string origName(origFileName);
+  Engines::fileRef_var theFileRef = Engines::fileRef::_nil();
+
+  if (origName[0] != '/')
+  {
+    INFOS("path of file to copy must be an absolute path begining with '/'");
+    return Engines::fileRef::_nil();
+  }
+
+  if (CORBA::is_nil(_fileRef_map[origName]))
+  {
+    CORBA::Object_var obj=_poa->id_to_reference(*_id);
+    Engines::Container_var pCont = Engines::Container::_narrow(obj);
+    fileRef_i* aFileRef = new fileRef_i(pCont, origFileName);
+    theFileRef = Engines::fileRef::_narrow(aFileRef->_this());
+    _numInstanceMutex.lock() ; // lock to be alone (stl container write)
+    _fileRef_map[origName] = theFileRef;
+    _numInstanceMutex.unlock() ;
+  }
+
+  theFileRef =  Engines::fileRef::_duplicate(_fileRef_map[origName]);
+  ASSERT(! CORBA::is_nil(theFileRef));
+  return theFileRef._retn();
+}
+
 //=============================================================================
+/*! 
+ *  CORBA method:
+ *  \return a reference to the fileTransfer object
+ */
+//=============================================================================
+
+Engines::fileTransfer_ptr
+Engines_Parallel_Container_i::getFileTransfer()
+{
+  Engines::fileTransfer_var aFileTransfer
+    = Engines::fileTransfer::_duplicate(_fileTransfer);
+  return aFileTransfer._retn();
+}
+
+
+Engines::Salome_file_ptr 
+Engines_Parallel_Container_i::createSalome_file(const char* origFileName) 
+{
+  string origName(origFileName);
+  if (CORBA::is_nil(_Salome_file_map[origName]))
+  {
+    Salome_file_i* aSalome_file = new Salome_file_i();
+    try 
+    {
+      aSalome_file->setLocalFile(origFileName);
+      aSalome_file->recvFiles();
+    }
+    catch (const SALOME::SALOME_Exception& e)
+    {
+      return Engines::Salome_file::_nil();
+    }
+
+    Engines::Salome_file_var theSalome_file = Engines::Salome_file::_nil();
+    theSalome_file = Engines::Salome_file::_narrow(aSalome_file->_this());
+    _numInstanceMutex.lock() ; // lock to be alone (stl container write)
+    _Salome_file_map[origName] = theSalome_file;
+    _numInstanceMutex.unlock() ;
+  }
+
+  Engines::Salome_file_ptr theSalome_file =  
+    Engines::Salome_file::_duplicate(_Salome_file_map[origName]);
+  ASSERT(!CORBA::is_nil(theSalome_file));
+  return theSalome_file;
+}
+
+
+//=============================================================================
+//! Finds an already existing component instance or create a new instance
 /*! 
  *  C++ method: Finds an already existing servant instance of a component, or
  *              create an instance.
@@ -472,7 +655,6 @@ bool Engines_Parallel_Container_i::Kill_impl()
  *  \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:
@@ -488,65 +670,44 @@ bool Engines_Parallel_Container_i::Kill_impl()
 //=============================================================================
 
 Engines::Component_ptr
-Engines_Parallel_Container_i::find_or_create_instance(string genericRegisterName,
-                                                     string componentLibraryName)
+Engines_Parallel_Container_i::find_or_create_instance(string genericRegisterName)
 {
-  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
+  Engines::Component_var iobject = Engines::Component::_nil();
+  try
   {
+    string aGenRegisterName = genericRegisterName;
     // --- find a registered instance in naming service, or create
-
-    string component_registerBase =
-      _containerName + "/" + aGenRegisterName;
-    Engines::Component_var iobject = Engines::Component::_nil() ;
-    try
+    string component_registerBase = _containerName + "/" + aGenRegisterName;
+    CORBA::Object_var obj = _NS->ResolveFirst(component_registerBase.c_str());
+    if (CORBA::is_nil( obj ))
     {
-      CORBA::Object_var obj =
-       _NS->ResolveFirst( component_registerBase.c_str());
-      if ( CORBA::is_nil( obj ) )
+      iobject = create_component_instance(genericRegisterName.c_str(), 
+                                         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)  // monoStudy instance: NOK
       {
-       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");
-       }
+       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();
   }
+  catch (...)
+  {
+    INFOS( "Container_i::load_impl catched" ) ;
+  }
+  return iobject._retn();
 }
 
 //=============================================================================
+//! Create a new Python component instance 
 /*! 
  *  C++ method: create a servant instance of a component.
  *  \param genericRegisterName    Name of the component instance to register
@@ -566,19 +727,78 @@ Engines_Parallel_Container_i::find_or_create_instance(string genericRegisterName
  *  component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
  */
 //=============================================================================
+Engines::Component_ptr
+Engines_Parallel_Container_i::createPythonInstance(string genericRegisterName, int studyId)
+{
+
+  Engines::Component_var iobject = Engines::Component::_nil();
 
+  _numInstanceMutex.lock();
+  _numInstance++;
+  int numInstance = _numInstance;
+  _numInstanceMutex.unlock();
+  char aNumI[12];
+  sprintf( aNumI , "%d" , numInstance ) ;
+  string instanceName = genericRegisterName + "_inst_" + aNumI ;
+  string component_registerName = _containerName + "/" + instanceName;
+
+  Py_ACQUIRE_NEW_THREAD;
+  PyObject *mainmod = PyImport_AddModule("__main__");
+  PyObject *globals = PyModule_GetDict(mainmod);
+  PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
+  PyObject *result = PyObject_CallMethod(pyCont,
+                                        (char*)"create_component_instance",
+                                        (char*)"ssl",
+                                        genericRegisterName.c_str(),
+                                        instanceName.c_str(),
+                                        studyId);
+  std::string iors = PyString_AsString(result);
+  Py_DECREF(result);
+  Py_RELEASE_NEW_THREAD;
+
+  if( iors!="" )
+  {
+    CORBA::Object_var obj = _orb->string_to_object(iors.c_str());
+    iobject = Engines::Component::_narrow(obj);
+    _listInstances_map[instanceName] = iobject;
+  }
+  else
+    std::cerr << "createPythonInstance ior is empty ! Error in creation" << std::endl;
+
+  return iobject._retn();
+}
+
+//=============================================================================
+//! Create a new CPP component instance 
+/*! 
+ *  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_Parallel_Container_i::createInstance(string genericRegisterName,
-                                            void *handle,
-                                            int studyId)
+Engines_Parallel_Container_i::createCPPInstance(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, 
@@ -586,14 +806,19 @@ Engines_Parallel_Container_i::createInstance(string genericRegisterName,
      const char *, 
      const char *) ;
 
-  FACTORY_FUNCTION Component_factory
-    = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
+  FACTORY_FUNCTION Component_factory = NULL;
+#ifndef WIN32
+  Component_factory = (FACTORY_FUNCTION)dlsym( handle, factory_name.c_str() );
+#else
+  Component_factory = (FACTORY_FUNCTION)GetProcAddress( (HINSTANCE)handle, factory_name.c_str() );
+#endif
 
-  char *error ;
-  if ( (error = dlerror() ) != NULL)
+  if (!Component_factory)
   {
     INFOS("Can't resolve symbol: " + factory_name);
-    SCRUTE(error);
+#ifndef WIN32
+    INFOS("dlerror() result is : " << dlerror());
+#endif
     return Engines::Component::_nil() ;
   }
 
@@ -601,26 +826,31 @@ Engines_Parallel_Container_i::createInstance(string genericRegisterName,
   Engines::Component_var iobject = Engines::Component::_nil() ;
   try
   {
-    _numInstanceMutex.lock() ; // lock on the instance number
-    _numInstance++ ;
-    int numInstance = _numInstance ;
-    _numInstanceMutex.unlock() ;
+    _numInstanceMutex.lock()
+    _numInstance++;
+    int numInstance = _numInstance;
+    _numInstanceMutex.unlock();
 
     char aNumI[12];
-    sprintf( aNumI , "%d" , numInstance ) ;
-    string instanceName = aGenRegisterName + "_inst_" + aNumI ;
+    sprintf( aNumI , "%d" , numInstance );
+    string instanceName = aGenRegisterName + "_inst_" + aNumI;
     string component_registerName =
       _containerName + "/" + instanceName;
 
     // --- Instanciate required CORBA object
 
-    PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
+    PortableServer::ObjectId *id; //not owner, do not delete (nore use var)
     id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str(),
-                              aGenRegisterName.c_str() ) ;
+                              aGenRegisterName.c_str() );
+    if (id == NULL)
+    {
+      INFOS("Factory function returns NULL !");
+      return iobject._retn();
+    }
 
     // --- get reference & servant from id
     CORBA::Object_var obj = _poa->id_to_reference(*id);
-    iobject = Engines::Component::_narrow(obj) ;
+    iobject = Engines::Component::_narrow(obj);
 
     Engines_Component_i *servant = 
       dynamic_cast<Engines_Component_i*>(_poa->reference_to_servant(iobject));
@@ -628,21 +858,31 @@ Engines_Parallel_Container_i::createInstance(string genericRegisterName,
     servant->_remove_ref(); // compensate previous id_to_reference 
     _listInstances_map[instanceName] = iobject;
     _cntInstances_map[aGenRegisterName] += 1;
+#if defined(_DEBUG_) || defined(_DEBUG)
     bool ret_studyId = servant->setStudyId(studyId);
     ASSERT(ret_studyId);
+#else
+    servant->setStudyId(studyId);
+#endif
 
     // --- register the engine under the name
     //     containerName(.dir)/instanceName(.object)
-    _NS->Register(iobject , component_registerName.c_str()) ;
-    MESSAGE( component_registerName.c_str() << " bound" ) ;
+    _NS->Register(iobject , component_registerName.c_str());
+    MESSAGE( component_registerName.c_str() << " bound" );
   }
   catch (...)
   {
-    INFOS( "Container_i::createInstance exception catched" ) ;
+    INFOS( "Container_i::createInstance exception catched" );
   }
   return iobject._retn();
 }
 
+void
+Engines_Parallel_Container_i::create_paco_component_node_instance(const char* componentName,
+                                                                 CORBA::Long studyId)
+{
+}
+
 Engines::Component_ptr
 Engines_Parallel_Container_i::createParallelInstance(string genericRegisterName,
                                                     void *handle,
@@ -733,7 +973,6 @@ Engines_Parallel_Container_i::createParallelInstance(string genericRegisterName,
   string instanceName = aGenRegisterName + "_inst_" + aNumI ;
 
   string component_registerName = _containerName + "/" + instanceName;
-  string hostname = Kernel_Utils::GetHostname();
 
   CORBA::Object_var temp = _NS->Resolve(component_registerName.c_str());
   Engines::Component_var obj_proxy = Engines::Component::_narrow(temp);
@@ -801,6 +1040,7 @@ Engines_Parallel_Container_i::createParallelInstance(string genericRegisterName,
 }
 
 //=============================================================================
+//! Decrement component instance reference count
 /*! 
  *
  */
@@ -808,26 +1048,30 @@ Engines_Parallel_Container_i::createParallelInstance(string genericRegisterName,
 
 void Engines_Parallel_Container_i::decInstanceCnt(string genericRegisterName)
 {
-  string aGenRegisterName =genericRegisterName;
-  MESSAGE("Engines_Parallel_Container_i::decInstanceCnt " << aGenRegisterName);
-  ASSERT(_cntInstances_map[aGenRegisterName] > 0); 
-  _numInstanceMutex.lock(); // lock to be alone
-  // (see finalize_removal, load_component_Library)
-  _cntInstances_map[aGenRegisterName] -= 1;
-  SCRUTE(_cntInstances_map[aGenRegisterName]);
-  if (_cntInstances_map[aGenRegisterName] == 0)
+  if(_cntInstances_map.count(genericRegisterName) !=0 )
   {
-    string impl_name =
-      Engines_Component_i::GetDynLibraryName(aGenRegisterName.c_str());
-    SCRUTE(impl_name);
-    void* handle = _library_map[impl_name];
-    ASSERT(handle);
-    _toRemove_map[impl_name] = handle;
+    string aGenRegisterName =genericRegisterName;
+    MESSAGE("Engines_Parallel_Container_i::decInstanceCnt " << aGenRegisterName);
+    ASSERT(_cntInstances_map[aGenRegisterName] > 0); 
+    _numInstanceMutex.lock(); // lock to be alone
+    // (see finalize_removal, load_component_Library)
+    _cntInstances_map[aGenRegisterName] -= 1;
+    SCRUTE(_cntInstances_map[aGenRegisterName]);
+    if (_cntInstances_map[aGenRegisterName] == 0)
+    {
+      string impl_name =
+       Engines_Component_i::GetDynLibraryName(aGenRegisterName.c_str());
+      SCRUTE(impl_name);
+      void* handle = _library_map[impl_name];
+      ASSERT(handle);
+      _toRemove_map[impl_name] = handle;
+    }
+    _numInstanceMutex.unlock();
   }
-  _numInstanceMutex.unlock();
 }
 
 //=============================================================================
+//! Indicate if container is a python one
 /*! 
  *  Retrieves only with container naming convention if it is a python container
  */
@@ -836,10 +1080,6 @@ void Engines_Parallel_Container_i::decInstanceCnt(string genericRegisterName)
 bool Engines_Parallel_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;
 }
 
@@ -861,6 +1101,7 @@ void ActSigIntHandler()
   // (SIGINT | SIGUSR1) :
   // it must be only one signal ===> one call for SIGINT 
   // and an other one for SIGUSR1
+
 #ifndef WIN32
   if ( sigaction( SIGINT , &SigIntAct, NULL ) ) {
     perror("SALOME_Container main ") ;
@@ -870,6 +1111,12 @@ void ActSigIntHandler()
     perror("SALOME_Container main ") ;
     exit(0) ;
   }
+  if ( sigaction( SIGUSR2 , &SigIntAct, NULL ) )
+  {
+    perror("SALOME_Container main ") ;
+    exit(0) ;
+  }
+
   //PAL9042 JR : during the execution of a Signal Handler (and of methods called through Signal Handlers)
   //             use of streams (and so on) should never be used because :
   //             streams of C++ are naturally thread-safe and use pthread_mutex_lock ===>
@@ -884,7 +1131,8 @@ void ActSigIntHandler()
 
 }
 
-void SetCpuUsed() ;
+void SetCpuUsed();
+void CallCancelThread();
 
 #ifndef WIN32
 void SigIntHandler(int what , siginfo_t * siginfo ,
@@ -909,6 +1157,10 @@ void SigIntHandler(int what , siginfo_t * siginfo ,
     if ( siginfo->si_signo == SIGUSR1 ) {
       SetCpuUsed() ;
     }
+    else if ( siginfo->si_signo == SIGUSR2 )
+    {
+      CallCancelThread() ;
+    }
     else {
       _Sleeping = true ;
       //      MESSAGE("SigIntHandler BEGIN sleeping.") ;
@@ -950,120 +1202,3 @@ void SigIntHandler( int what ) {
 }
 #endif
 
-//=============================================================================
-/*! 
- *  CORBA method: get or create a fileRef object associated to a local file
- *  (a file on the computer on which runs the container server), which stores
- *  a list of (machine, localFileName) corresponding to copies already done.
- * 
- *  \param  origFileName absolute path for a local file to copy on other
- *          computers
- *  \return a fileRef object associated to the file.
- */
-//=============================================================================
-
-Engines::fileRef_ptr
-Engines_Parallel_Container_i::createFileRef(const char* origFileName)
-{
-  string origName(origFileName);
-  Engines::fileRef_var theFileRef = Engines::fileRef::_nil();
-
-  if (origName[0] != '/')
-  {
-    INFOS("path of file to copy must be an absolute path begining with '/'");
-    return Engines::fileRef::_nil();
-  }
-
-  if (CORBA::is_nil(_fileRef_map[origName]))
-  {
-    CORBA::Object_var obj=_poa->id_to_reference(*_id);
-    Engines::Container_var pCont = Engines::Container::_narrow(obj);
-    fileRef_i* aFileRef = new fileRef_i(pCont, origFileName);
-    theFileRef = Engines::fileRef::_narrow(aFileRef->_this());
-    _numInstanceMutex.lock() ; // lock to be alone (stl container write)
-    _fileRef_map[origName] = theFileRef;
-    _numInstanceMutex.unlock() ;
-  }
-
-  theFileRef =  Engines::fileRef::_duplicate(_fileRef_map[origName]);
-  ASSERT(! CORBA::is_nil(theFileRef));
-  return theFileRef._retn();
-}
-
-//=============================================================================
-/*! 
- *  CORBA method:
- *  \return a reference to the fileTransfer object
- */
-//=============================================================================
-
-Engines::fileTransfer_ptr
-Engines_Parallel_Container_i::getFileTransfer()
-{
-  Engines::fileTransfer_var aFileTransfer
-    = Engines::fileTransfer::_duplicate(_fileTransfer);
-  return aFileTransfer._retn();
-}
-
-
-Engines::Salome_file_ptr 
-Engines_Parallel_Container_i::createSalome_file(const char* origFileName) 
-{
-  string origName(origFileName);
-  if (CORBA::is_nil(_Salome_file_map[origName]))
-  {
-    Salome_file_i* aSalome_file = new Salome_file_i();
-    try 
-    {
-      aSalome_file->setLocalFile(origFileName);
-      aSalome_file->recvFiles();
-    }
-    catch (const SALOME::SALOME_Exception& e)
-    {
-      return Engines::Salome_file::_nil();
-    }
-
-    Engines::Salome_file_var theSalome_file = Engines::Salome_file::_nil();
-    theSalome_file = Engines::Salome_file::_narrow(aSalome_file->_this());
-    _numInstanceMutex.lock() ; // lock to be alone (stl container write)
-    _Salome_file_map[origName] = theSalome_file;
-    _numInstanceMutex.unlock() ;
-  }
-
-  Engines::Salome_file_ptr theSalome_file =  
-    Engines::Salome_file::_duplicate(_Salome_file_map[origName]);
-  ASSERT(!CORBA::is_nil(theSalome_file));
-  return theSalome_file;
-}
-
-//=============================================================================
-/*! 
- *  CORBA attribute: Container working directory 
- */
-//=============================================================================
-
-char* 
-Engines_Parallel_Container_i::workingdir()
-{
-  char wd[256];
-  getcwd (wd,256);
-  return CORBA::string_dup(wd) ;
-}
-
-//=============================================================================
-/*! 
- *  CORBA attribute: Container log file name
- */
-//=============================================================================
-
-char* 
-Engines_Parallel_Container_i::logfilename()
-{
-  return CORBA::string_dup(_logfilename.c_str()) ;
-}
-
-void 
-Engines_Parallel_Container_i::logfilename(const char* name)
-{
-  _logfilename=name;
-}
index a35014c436e666bbe0aab56f61545212753c19a3..492f28bc195363072009df2d65321064959ca914 100644 (file)
 //  SALOME_ParallelContainer : implementation of container and engine for Parallel Kernel
 //  File   : SALOME_ParallelContainer_i.hxx
 //  Author : André RIBES, EDF
-//  Author : Paul RASCLE, EDF - MARC TAJCHMAN, CEA
 //
 #ifndef _SALOME_PARALLEL_CONTAINER_I_HXX_
 #define _SALOME_PARALLEL_CONTAINER_I_HXX_
 
 #include <SALOMEconfig.h>
 
-#include "SALOME_ComponentPaCO_Engines_Container_server.hxx"
+#include "SALOME_PACOExtensionPaCO_Engines_PACO_Container_server.hxx"
+#include "SALOME_ParallelGlobalProcessVar_i.hxx"
 
 #include <iostream>
 #include <signal.h>
@@ -55,17 +55,15 @@ class SALOME_NamingService;
 #endif
 
 class CONTAINER_EXPORT Engines_Parallel_Container_i:
-  /*  public virtual POA_Engines::Container, */
-  public Engines::Container_serv,
-  public virtual PortableServer::RefCountServantBase
+  virtual public Engines::PACO_Container_serv,
+  virtual public ParallelGlobalProcessVar_i,
+  virtual public PortableServer::RefCountServantBase
 {
 public:
-  Engines_Parallel_Container_i(CORBA::ORB_ptr orb, char * ior, int rank);
   Engines_Parallel_Container_i(CORBA::ORB_ptr orb, char * ior, int rank,
                      PortableServer::POA_ptr poa,
                      char * containerName ,
                       int argc, char* argv[],
-                     bool activAndRegist = true,
                      bool isServantAloneInProcess = true);
   virtual ~Engines_Parallel_Container_i();
 
@@ -85,6 +83,9 @@ public:
   load_impl(const char* nameToRegister,
            const char* componentName);
 
+  void
+  create_paco_component_node_instance( const char* componentName,
+                                      CORBA::Long studyId); // 0 for multiStudy
 
   void remove_impl(Engines::Component_ptr component_i);
   void finalize_removal();
@@ -104,13 +105,16 @@ public:
   // --- local C++ methods
 
   Engines::Component_ptr
-  find_or_create_instance( std::string genericRegisterName,
-                          std::string componentLibraryName);
+  find_or_create_instance(std::string genericRegisterName);
 
   Engines::Component_ptr
-  createInstance(std::string genericRegisterName,
-                void *handle,
-                int studyId);
+  createCPPInstance(std::string genericRegisterName,
+                   void *handle,
+                   int studyId);
+
+  Engines::Component_ptr
+  createPythonInstance(std::string genericRegisterName,
+                      int studyId);
 
   Engines::Component_ptr
   createParallelInstance(std::string genericRegisterName,
@@ -131,32 +135,31 @@ public:
   Engines::fileTransfer_ptr getFileTransfer();
 
   virtual Engines::Salome_file_ptr createSalome_file(const char* origFileName);
-protected:
-
-  static std::map<std::string, int> _cntInstances_map;
-  static std::map<std::string, void *> _library_map; // library names, loaded
-  static std::map<std::string, void *> _toRemove_map;// library names to remove
-  static omni_mutex _numInstanceMutex ; // lib and instance protection
 
-  bool _isSupervContainer;
+protected:
 
-  SALOME_NamingService *_NS ;
+  SALOME_NamingService *_NS;
+  std::string _hostname;
   std::string _library_path;
   std::string _containerName;
   std::string _logfilename;
   CORBA::ORB_var _orb;
   PortableServer::POA_var _poa;
-  PortableServer::ObjectId * _id ;
-  int _numInstance ;
-  std::map<std::string,Engines::Component_var> _listInstances_map;
-  std::map<std::string,Engines::fileRef_var> _fileRef_map;
-  std::map<std::string,Engines::Salome_file_var> _Salome_file_map;
+  PortableServer::ObjectId * _id;
+  int _numInstance;
+  int    _argc;
+  char** _argv;
+  CORBA::Long   _pid;
+  bool   _isServantAloneInProcess;
   Engines::fileTransfer_var _fileTransfer;
 
-  int    _argc ;
-  char** _argv ;
-  long   _pid;
-  bool   _isServantAloneInProcess;
+  typedef std::map<std::string,Engines::Component_var> _listInstances_map_t;
+  typedef std::map<std::string,Engines::fileRef_var> _fileRef_map_t;
+  typedef std::map<std::string,Engines::Salome_file_var> _Salome_file_map_t;
+  _listInstances_map_t _listInstances_map;
+  _fileRef_map_t _fileRef_map;
+  _Salome_file_map_t _Salome_file_map;
+
 };
 
 #endif
diff --git a/src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.cxx b/src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.cxx
new file mode 100644 (file)
index 0000000..8217d00
--- /dev/null
@@ -0,0 +1,37 @@
+//  Copyright (C) 2007-2009  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  SALOME_ParallelContainer : implementation of container and engine for ParallelKernel
+//  File   : SALOME_ParallelContainer_i.cxx
+//  Author : André RIBES, EDF
+
+#include "SALOME_ParallelGlobalProcessVar_i.hxx"
+
+// Ces variables globales de classes permettent de ne charger
+// qu'une seule fois une bibliothèque dynamique.
+std::map<std::string, int>    ParallelGlobalProcessVar_i::_cntInstances_map;
+std::map<std::string, void *> ParallelGlobalProcessVar_i::_library_map;
+std::map<std::string, void *> ParallelGlobalProcessVar_i::_toRemove_map;
+omni_mutex ParallelGlobalProcessVar_i::_numInstanceMutex ;
+
+ParallelGlobalProcessVar_i::ParallelGlobalProcessVar_i() {}
+
+ParallelGlobalProcessVar_i::~ParallelGlobalProcessVar_i() {}
diff --git a/src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.hxx b/src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.hxx
new file mode 100644 (file)
index 0000000..39fe6d1
--- /dev/null
@@ -0,0 +1,59 @@
+//  Copyright (C) 2007-2009  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  SALOME_ParallelContainer : implementation of container and engine for Parallel Kernel
+//  File   : SALOME_ParallelContainer_i.hxx
+//  Author : André RIBES, EDF
+//
+#ifndef _SALOME_PARALLEL_GLOBALPROCESSVAR_I_HXX_
+#define _SALOME_PARALLEL_GLOBALPROCESSVAR_I_HXX_
+
+#ifdef WIN32
+# ifdef CONTAINER_EXPORTS
+#  define CONTAINER_EXPORT __declspec( dllexport )
+# else
+#  define CONTAINER_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CONTAINER_EXPORT
+#endif
+
+#include <SALOMEconfig.h>
+#include <omnithread.h>
+#include <map>
+#include <string>
+
+class CONTAINER_EXPORT ParallelGlobalProcessVar_i
+{
+public:
+  ParallelGlobalProcessVar_i();
+  virtual ~ParallelGlobalProcessVar_i();
+
+protected:
+  // Voir commentaire dans le fichier .cxx
+  static std::map<std::string, int> _cntInstances_map;
+  static std::map<std::string, void *> _library_map; // library names, loaded
+  static std::map<std::string, void *> _toRemove_map;// library names to remove
+  static omni_mutex _numInstanceMutex ; // lib and instance protection
+};
+
+#endif
+