From 514a75a2f251556423870524f2aeca7e61c550f0 Mon Sep 17 00:00:00 2001 From: ribes Date: Thu, 12 Mar 2009 16:08:47 +0000 Subject: [PATCH] - Start of a new version of PACO integration with SALOME --- idl/DSC_Engines.idl | 24 - idl/DSC_Engines.xml | 7 - idl/Makefile.am | 77 +- idl/SALOME_Component.idl | 48 - idl/SALOME_Component.xml | 18 - idl/SALOME_PACOExtension.idl | 117 +++ idl/SALOME_PACOExtension.xml | 52 ++ idl/SALOME_ParamPorts.idl | 43 + idl/SALOME_ParamPorts.xml | 55 ++ idl/SALOME_Ports.idl | 15 +- idl/SALOME_Ports.xml | 23 - src/DSC/ParallelDSC/ParallelDSC_i.hxx | 2 +- .../Param_Double_Port_provides_i.hxx | 2 +- .../ParallelDSC/Param_Double_Port_uses_i.hxx | 2 +- src/ParallelContainer/Makefile.am | 9 +- .../Parallel_Salome_file_i.hxx | 2 +- .../SALOME_ParallelComponent_i.hxx | 2 +- .../SALOME_ParallelContainerProxyDummy.cxx | 4 +- .../SALOME_ParallelContainerProxyMpi.cxx | 6 +- .../SALOME_ParallelContainerProxy_i.cxx | 219 ++++- .../SALOME_ParallelContainerProxy_i.hxx | 35 +- .../SALOME_ParallelContainer_i.cxx | 845 ++++++++++-------- .../SALOME_ParallelContainer_i.hxx | 61 +- .../SALOME_ParallelGlobalProcessVar_i.cxx | 37 + .../SALOME_ParallelGlobalProcessVar_i.hxx | 59 ++ 25 files changed, 1201 insertions(+), 563 deletions(-) create mode 100644 idl/SALOME_PACOExtension.idl create mode 100644 idl/SALOME_PACOExtension.xml create mode 100644 idl/SALOME_ParamPorts.idl create mode 100644 idl/SALOME_ParamPorts.xml create mode 100644 src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.cxx create mode 100644 src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.hxx diff --git a/idl/DSC_Engines.idl b/idl/DSC_Engines.idl index cbe349e27..f37911362 100644 --- a/idl/DSC_Engines.idl +++ b/idl/DSC_Engines.idl @@ -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 diff --git a/idl/DSC_Engines.xml b/idl/DSC_Engines.xml index 9148b8b18..0f3ec937f 100644 --- a/idl/DSC_Engines.xml +++ b/idl/DSC_Engines.xml @@ -38,13 +38,6 @@ distributed - - Parallel_DSC - - set_paco_proxy - distributed - - Superv_Component diff --git a/idl/Makefile.am b/idl/Makefile.am index 13a90697c..d724adcc6 100644 --- a/idl/Makefile.am +++ b/idl/Makefile.am @@ -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 diff --git a/idl/SALOME_Component.idl b/idl/SALOME_Component.idl index e47f886d0..878d2e6cd 100644 --- a/idl/SALOME_Component.idl +++ b/idl/SALOME_Component.idl @@ -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 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 diff --git a/idl/SALOME_Component.xml b/idl/SALOME_Component.xml index 9f5984394..169e7543d 100644 --- a/idl/SALOME_Component.xml +++ b/idl/SALOME_Component.xml @@ -33,14 +33,6 @@ ping distributed - - create_component_instance - distributed - - - load_component_Library - distributed - Component @@ -53,21 +45,11 @@ distributed - - Parallel_Component - - send_parallel_proxy_object - distributed - - fileTransfer Salome_file - - Parallel_Salome_file - diff --git a/idl/SALOME_PACOExtension.idl b/idl/SALOME_PACOExtension.idl new file mode 100644 index 000000000..01cd4f818 --- /dev/null +++ b/idl/SALOME_PACOExtension.idl @@ -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 index 000000000..2c7a0593a --- /dev/null +++ b/idl/SALOME_PACOExtension.xml @@ -0,0 +1,52 @@ + + + + + Engines + + Parallel_Component + + send_parallel_proxy_object + distributed + + + + PACO_Container + + + Parallel_DSC + + set_paco_proxy + distributed + + + + Parallel_Salome_file + + + + diff --git a/idl/SALOME_ParamPorts.idl b/idl/SALOME_ParamPorts.idl new file mode 100644 index 000000000..9ef4e6596 --- /dev/null +++ b/idl/SALOME_ParamPorts.idl @@ -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 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 index 000000000..e6d8a3fae --- /dev/null +++ b/idl/SALOME_ParamPorts.xml @@ -0,0 +1,55 @@ + + + + + Ports + + Param_Double_Port + + put + distributed + + param_data + + BasicBC + + + + + get_results + distributed + + param_results + + GaBro + + + + + + + diff --git a/idl/SALOME_Ports.idl b/idl/SALOME_Ports.idl index 5763447aa..2f6b5b3ab 100644 --- a/idl/SALOME_Ports.idl +++ b/idl/SALOME_Ports.idl @@ -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 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_Ports.xml b/idl/SALOME_Ports.xml index bb3e7aa1e..158637132 100644 --- a/idl/SALOME_Ports.xml +++ b/idl/SALOME_Ports.xml @@ -36,28 +36,5 @@ Data_Port - - Param_Double_Port - - put - distributed - - param_data - - BasicBC - - - - - get_results - distributed - - param_results - - GaBro - - - - diff --git a/src/DSC/ParallelDSC/ParallelDSC_i.hxx b/src/DSC/ParallelDSC/ParallelDSC_i.hxx index e83d57d06..ac9273c46 100644 --- a/src/DSC/ParallelDSC/ParallelDSC_i.hxx +++ b/src/DSC/ParallelDSC/ParallelDSC_i.hxx @@ -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: diff --git a/src/DSC/ParallelDSC/Param_Double_Port_provides_i.hxx b/src/DSC/ParallelDSC/Param_Double_Port_provides_i.hxx index 8d638e296..3eba98b21 100644 --- a/src/DSC/ParallelDSC/Param_Double_Port_provides_i.hxx +++ b/src/DSC/ParallelDSC/Param_Double_Port_provides_i.hxx @@ -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" diff --git a/src/DSC/ParallelDSC/Param_Double_Port_uses_i.hxx b/src/DSC/ParallelDSC/Param_Double_Port_uses_i.hxx index 745063489..48bbe04e1 100644 --- a/src/DSC/ParallelDSC/Param_Double_Port_uses_i.hxx +++ b/src/DSC/ParallelDSC/Param_Double_Port_uses_i.hxx @@ -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" diff --git a/src/ParallelContainer/Makefile.am b/src/ParallelContainer/Makefile.am index 62d705aac..dc20c67ab 100644 --- a/src/ParallelContainer/Makefile.am +++ b/src/ParallelContainer/Makefile.am @@ -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) diff --git a/src/ParallelContainer/Parallel_Salome_file_i.hxx b/src/ParallelContainer/Parallel_Salome_file_i.hxx index 07ccd0992..ee7ec3f04 100644 --- a/src/ParallelContainer/Parallel_Salome_file_i.hxx +++ b/src/ParallelContainer/Parallel_Salome_file_i.hxx @@ -32,7 +32,7 @@ #include #include -#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: diff --git a/src/ParallelContainer/SALOME_ParallelComponent_i.hxx b/src/ParallelContainer/SALOME_ParallelComponent_i.hxx index 49cbbfaa0..11c0e8385 100644 --- a/src/ParallelContainer/SALOME_ParallelComponent_i.hxx +++ b/src/ParallelContainer/SALOME_ParallelComponent_i.hxx @@ -38,7 +38,7 @@ #include #include -#include "SALOME_ComponentPaCO_Engines_Parallel_Component_server.hxx" +#include "SALOME_PACOExtensionPaCO_Engines_Parallel_Component_server.hxx" #include "NOTIFICATION.hxx" #include "RegistryConnexion.hxx" diff --git a/src/ParallelContainer/SALOME_ParallelContainerProxyDummy.cxx b/src/ParallelContainer/SALOME_ParallelContainerProxyDummy.cxx index f00184b64..683a6f660 100644 --- a/src/ParallelContainer/SALOME_ParallelContainerProxyDummy.cxx +++ b/src/ParallelContainer/SALOME_ParallelContainerProxyDummy.cxx @@ -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()); diff --git a/src/ParallelContainer/SALOME_ParallelContainerProxyMpi.cxx b/src/ParallelContainer/SALOME_ParallelContainerProxyMpi.cxx index 73c9b3331..2ed477903 100644 --- a/src/ParallelContainer/SALOME_ParallelContainerProxyMpi.cxx +++ b/src/ParallelContainer/SALOME_ParallelContainerProxyMpi.cxx @@ -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(); diff --git a/src/ParallelContainer/SALOME_ParallelContainerProxy_i.cxx b/src/ParallelContainer/SALOME_ParallelContainerProxy_i.cxx index dfdcab72d..90b61996b 100644 --- a/src/ParallelContainer/SALOME_ParallelContainerProxy_i.cxx +++ b/src/ParallelContainer/SALOME_ParallelContainerProxy_i.cxx @@ -22,23 +22,238 @@ // 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; +} diff --git a/src/ParallelContainer/SALOME_ParallelContainerProxy_i.hxx b/src/ParallelContainer/SALOME_ParallelContainerProxy_i.hxx index ef6e66367..bef0b12b7 100644 --- a/src/ParallelContainer/SALOME_ParallelContainerProxy_i.hxx +++ b/src/ParallelContainer/SALOME_ParallelContainerProxy_i.hxx @@ -22,24 +22,51 @@ // 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 +#include +#include 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 _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 _parlibfct_map; + int _numInstance; + std::string _containerName; + PortableServer::POA_var _poa; + PortableServer::ObjectId * _id; + SALOME_NamingService *_NS; }; #endif diff --git a/src/ParallelContainer/SALOME_ParallelContainer_i.cxx b/src/ParallelContainer/SALOME_ParallelContainer_i.cxx index 2f45c8658..af29dbc61 100644 --- a/src/ParallelContainer/SALOME_ParallelContainer_i.cxx +++ b/src/ParallelContainer/SALOME_ParallelContainer_i.cxx @@ -21,45 +21,39 @@ // // 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 -#ifndef WIN32 -#else -#include -#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 #include #ifndef WIN32 +#include #include #include #else -#include "../../adm/win32/SALOME_WNT.hxx" #include #include +#include int SIGUSR1 = 1000; #endif #include -#include "utilities.h" -#include "Basics_Utils.hxx" + +#include +#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 Engines_Parallel_Container_i::_cntInstances_map; -map Engines_Parallel_Container_i::_library_map; -map 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::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 "<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::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::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::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(_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 - (_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(_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; -} diff --git a/src/ParallelContainer/SALOME_ParallelContainer_i.hxx b/src/ParallelContainer/SALOME_ParallelContainer_i.hxx index a35014c43..492f28bc1 100644 --- a/src/ParallelContainer/SALOME_ParallelContainer_i.hxx +++ b/src/ParallelContainer/SALOME_ParallelContainer_i.hxx @@ -22,14 +22,14 @@ // 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 -#include "SALOME_ComponentPaCO_Engines_Container_server.hxx" +#include "SALOME_PACOExtensionPaCO_Engines_PACO_Container_server.hxx" +#include "SALOME_ParallelGlobalProcessVar_i.hxx" #include #include @@ -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 _cntInstances_map; - static std::map _library_map; // library names, loaded - static std::map _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 _listInstances_map; - std::map _fileRef_map; - std::map _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 _listInstances_map_t; + typedef std::map _fileRef_map_t; + typedef std::map _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 index 000000000..8217d0037 --- /dev/null +++ b/src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.cxx @@ -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 ParallelGlobalProcessVar_i::_cntInstances_map; +std::map ParallelGlobalProcessVar_i::_library_map; +std::map 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 index 000000000..39fe6d126 --- /dev/null +++ b/src/ParallelContainer/SALOME_ParallelGlobalProcessVar_i.hxx @@ -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 +#include +#include +#include + +class CONTAINER_EXPORT ParallelGlobalProcessVar_i +{ +public: + ParallelGlobalProcessVar_i(); + virtual ~ParallelGlobalProcessVar_i(); + +protected: + // Voir commentaire dans le fichier .cxx + static std::map _cntInstances_map; + static std::map _library_map; // library names, loaded + static std::map _toRemove_map;// library names to remove + static omni_mutex _numInstanceMutex ; // lib and instance protection +}; + +#endif + -- 2.39.2