Salome HOME
PR: mergefrom_BR_GEAY_05Nov04
authorprascle <prascle>
Fri, 5 Nov 2004 12:56:36 +0000 (12:56 +0000)
committerprascle <prascle>
Fri, 5 Nov 2004 12:56:36 +0000 (12:56 +0000)
30 files changed:
configure.in.base
idl/Makefile.in
idl/SALOME_Comm.idl [new file with mode: 0644]
salome_adm/unix/config_files/check_lam.m4 [new file with mode: 0644]
salome_adm/unix/config_files/check_mpi.m4
salome_adm/unix/config_files/check_mpich.m4
salome_adm/unix/config_files/check_omniorb.m4
salome_adm/unix/config_files/check_sockets.m4 [new file with mode: 0644]
salome_adm/unix/make_commence.in
src/Communication/Makefile.in [new file with mode: 0644]
src/Communication/MultiCommException.cxx [new file with mode: 0644]
src/Communication/MultiCommException.hxx [new file with mode: 0644]
src/Communication/Receiver.cxx [new file with mode: 0644]
src/Communication/Receiver.hxx [new file with mode: 0644]
src/Communication/ReceiverFactory.cxx [new file with mode: 0644]
src/Communication/ReceiverFactory.hxx [new file with mode: 0644]
src/Communication/Receivers.cxx [new file with mode: 0644]
src/Communication/Receivers.hxx [new file with mode: 0644]
src/Communication/SALOMEMultiComm.cxx [new file with mode: 0644]
src/Communication/SALOMEMultiComm.hxx [new file with mode: 0644]
src/Communication/SALOME_Comm_i.cxx [new file with mode: 0644]
src/Communication/SALOME_Comm_i.hxx [new file with mode: 0644]
src/Communication/SenderFactory.cxx [new file with mode: 0644]
src/Communication/SenderFactory.hxx [new file with mode: 0644]
src/Container/Makefile.in
src/Container/SALOME_Container.cxx
src/MPIContainer/MPIContainer_i.cxx
src/MPIContainer/MPIObject_i.cxx
src/MPIContainer/Makefile.in
src/Makefile.in

index 46d005cb9f086d401427acdb0c4a7f9a55293cac..0eef838db2ab3e6fd9498899f4c078614e488d8a 100644 (file)
@@ -125,13 +125,29 @@ echo
 
 CHECK_BOOST
 
+echo
+echo ---------------------------------------------
+echo testing threads
+echo ---------------------------------------------
+echo
+
+ENABLE_PTHREADS
+
+dnl
+dnl ---------------------------------------------
+dnl testing MPI
+dnl ---------------------------------------------
+dnl
+
+CHECK_MPI
+
 dnl
 dnl ---------------------------------------------
-dnl testing MPICH
+dnl testing sockets
 dnl ---------------------------------------------
 dnl
 
-CHECK_MPICH
+CHECK_SOCKETS
 
 dnl
 dnl ---------------------------------------------
@@ -184,14 +200,6 @@ echo
 
 CHECK_SWIG
 
-echo
-echo ---------------------------------------------
-echo testing threads
-echo ---------------------------------------------
-echo
-
-ENABLE_PTHREADS
-
 echo
 echo ---------------------------------------------
 echo testing omniORB
@@ -308,12 +316,15 @@ echo ---------------------------------------------
 echo
 
 echo Configure
-variables="cc_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok med2_ok omniORB_ok occ_ok sip_ok pyqt_ok qwt_ok doxygen_ok graphviz_ok openpbs_ok"
+variables="cc_ok boost_ok lex_yacc_ok mpi_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok med2_ok omniORB_ok occ_ok sip_ok pyqt_ok qwt_ok doxygen_ok graphviz_ok openpbs_ok"
  
 for var in $variables
 do
-   printf "   %10s : " `echo \$var | sed -e "s,_ok,,"`
-   eval echo \$$var
+   eval toto=\$$var
+   if test x$toto != "x"; then
+     printf "   %10s : " `echo \$var | sed -e "s,_ok,,"`
+     eval echo \$$var
+   fi
 done
 
 echo
index 4dee4634d1d23cfcbf57868f4c73bd39883ddbb4..7de067f7454eff8be80916d2ee980c517707c64a 100644 (file)
@@ -12,6 +12,7 @@ VPATH=.
 
 IDL_FILES = \
   SALOME_Exception.idl \
+  SALOME_Comm.idl \
   SALOME_ModuleCatalog.idl \
   SALOME_DataTypeCatalog.idl \
   SALOME_RessourcesCatalog.idl \
diff --git a/idl/SALOME_Comm.idl b/idl/SALOME_Comm.idl
new file mode 100644 (file)
index 0000000..a01eca1
--- /dev/null
@@ -0,0 +1,81 @@
+#include "SALOME_Exception.idl"
+
+module SALOME {
+  
+  enum TypeOfDataTransmitted { _DOUBLE_,_INT_ };
+
+  enum TypeOfCommunication { CORBA_ , MPI_ , SOCKET_ };
+
+  typedef sequence<double> vectorOfDouble;
+  
+  typedef sequence<long> vectorOfLong;
+  
+  interface MultiCommClass {
+    void setProtocol(in TypeOfCommunication typ);
+  };
+
+  interface ServantLifeCycle {
+    void release();
+  };
+
+  interface Sender {
+    TypeOfDataTransmitted getTypeOfDataTransmitted();
+    Sender buildOtherWithProtocol(in TypeOfCommunication type);
+    void release();
+  };
+
+  //No compulsory copy between double and CORBA::Double
+  interface CorbaDoubleNCSender : Sender {
+    unsigned long getSize();
+    vectorOfDouble sendPart(in unsigned long n1,in unsigned long n2);
+    vectorOfDouble send();
+  };
+
+  //Compulsory copy between double and CORBA::Double
+  interface CorbaDoubleCSender : Sender {
+    unsigned long getSize();
+    //unsigned long getSize2();
+    vectorOfDouble sendPart(in unsigned long n1,in unsigned long n2);
+  };
+
+  //No compulsory copy between int and CORBA::Long
+  interface CorbaLongNCSender : Sender {
+    unsigned long getSize();
+    vectorOfLong sendPart(in unsigned long n1,in unsigned long n2);
+    vectorOfLong send();
+  };
+
+  //Compulsory copy between int and CORBA::Long
+  interface CorbaLongCSender : Sender {
+    unsigned long getSize();
+    vectorOfLong sendPart(in unsigned long n1,in unsigned long n2);
+  };
+
+  interface MPISender : Sender {
+    typedef struct Parameter {
+      unsigned long myproc;
+      unsigned long tag1;
+      unsigned long tag2;
+      string service;
+    } param;
+    param getParam();
+    void send();
+    void close(in param p);
+  };
+
+  interface SocketSender : Sender {
+    typedef struct Parameter {
+      unsigned long lstart;
+      unsigned long lend;
+      unsigned long myport;
+     string internet_address;
+    } param;
+    param getParam();
+    void initCom() raises(SALOME_Exception);
+    void acceptCom() raises(SALOME_Exception);
+    void closeCom();
+    void endOfCom() raises(SALOME_Exception);
+    void send();
+  };
+
+};
diff --git a/salome_adm/unix/config_files/check_lam.m4 b/salome_adm/unix/config_files/check_lam.m4
new file mode 100644 (file)
index 0000000..ab62ab4
--- /dev/null
@@ -0,0 +1,74 @@
+dnl  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+dnl 
+dnl  This library is free software; you can redistribute it and/or 
+dnl  modify it under the terms of the GNU Lesser General Public 
+dnl  License as published by the Free Software Foundation; either 
+dnl  version 2.1 of the License. 
+dnl 
+dnl  This library is distributed in the hope that it will be useful, 
+dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+dnl  Lesser General Public License for more details. 
+dnl 
+dnl  You should have received a copy of the GNU Lesser General Public 
+dnl  License along with this library; if not, write to the Free Software 
+dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+dnl 
+dnl  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+dnl
+dnl
+dnl
+
+AC_DEFUN([CHECK_LAM],[
+
+AC_REQUIRE([AC_PROG_CC])dnl
+
+AC_ARG_WITH(lam,
+           --with-lam=DIR root directory path of LAM installation,
+           WITHLAM="yes",WITHLAM="no")
+
+MPI_INCLUDES=""
+MPI_LIBS=""
+if test "$WITHLAM" = yes; then
+
+  echo
+  echo ---------------------------------------------
+  echo testing lam
+  echo ---------------------------------------------
+  echo
+  LAM_HOME=$withval
+
+  if test "$LAM_HOME"; then
+    MPI_INCLUDES="-I$LAM_HOME/include"
+    MPI_LIBS="-L$LAM_HOME/lib"
+  fi
+
+  CPPFLAGS_old="$CPPFLAGS"
+  CPPFLAGS="$MPI_INCLUDES $CPPFLAGS"
+  AC_CHECK_HEADER(mpi.h,WITHLAM="yes",WITHLAM="no")
+  CPPFLAGS="$CPPFLAGS_old"
+
+  if test "$WITHLAM" = "yes";then
+    AC_CHECK_LIB(util,openpty,,WITHLAM="no")
+    LIBS_old="$LIBS"
+    LDFLAGS_old="$LDFLAGS"
+    LDFLAGS="$MPI_LIBS $LDFLAGS"
+    AC_CHECK_LIB(lam,lam_mp_init,,WITHLAM="no")
+    AC_CHECK_LIB(mpi,MPI_Init,WITHLAM="yes",WITHLAM="no")
+    AC_CHECK_LIB(mpi,MPI_Publish_name,WITHMPI2="yes",WITHMPI2="no")
+    LDFLAGS="$LDFLAGS_old"
+    LIBS="$LIBS_old"
+  fi
+
+  if test "$WITHLAM" = "yes";then
+     mpi_ok=yes
+     MPI_LIBS="$MPI_LIBS -lmpi -llam"
+  else
+     mpi_ok=no
+  fi
+
+fi
+
+
+])dnl
index 51f271a9f16f30f5ebfdf469228005f5006c8a84..6c68d7053eda52cf4ed1f7faa49cf553cc64ce77 100644 (file)
@@ -50,21 +50,54 @@ if test "$WITHMPI" = yes; then
   CPPFLAGS="$CPPFLAGS_old"
 
   if test "$WITHMPI" = "yes";then
+    LIBS_old="$LIBS"
     LDFLAGS_old="$LDFLAGS"
     LDFLAGS="$MPI_LIBS $LDFLAGS"
     AC_CHECK_LIB(elan,elan_init,MPI_LIBS="$MPI_LIBS -lelan")
     AC_CHECK_LIB(mpi,MPI_Init,WITHMPI="yes",WITHMPI="no")
+    AC_CHECK_LIB(mpi,MPI_Publish_name,WITHMPI2="yes",WITHMPI2="no")
     LDFLAGS="$LDFLAGS_old"
+    LIBS="$LIBS_old"
   fi
 
   if test "$WITHMPI" = "yes";then
     mpi_ok=yes
     MPI_LIBS="$MPI_LIBS -lmpi"
+  else
+    mpi_ok=no
   fi
 
 fi
+
+if test "$WITHMPI" = no; then
+dnl
+dnl ---------------------------------------------
+dnl testing MPICH
+dnl ---------------------------------------------
+dnl
+
+  CHECK_MPICH
+
+  if test "$WITHMPICH" = no; then
+dnl
+dnl ---------------------------------------------
+dnl testing LAM
+dnl ---------------------------------------------
+dnl
+
+    CHECK_LAM
+
+  fi
+
+fi
+
+if test "$WITHMPI2" = "yes";then
+  CPPFLAGS="-DHAVE_MPI2 $CPPFLAGS"
+  CORBA_IDLCXXFLAGS="-DHAVE_MPI2 $CORBA_IDLCXXFLAGS"
+  CORBA_IDLPYFLAGS="-DHAVE_MPI2 $CORBA_IDLPYFLAGS"
+fi
+
 AC_SUBST(MPI_INCLUDES)
 AC_SUBST(MPI_LIBS)
-AC_SUBST(WITHMPI)
-
+AC_SUBST(mpi_ok)
 ])dnl
index cb4af538888fde4bb42c47a31994a28888b5b102..5b34bcd806519c49d89fcdb85818c8ba2fe5a763 100644 (file)
@@ -28,8 +28,8 @@ AC_ARG_WITH(mpich,
            --with-mpich=DIR root directory path of MPICH installation,
            WITHMPICH="yes",WITHMPICH="no")
 
-MPICH_INCLUDES=""
-MPICH_LIBS=""
+MPI_INCLUDES=""
+MPI_LIBS=""
 if test "$WITHMPICH" = yes; then
 
   echo
@@ -40,29 +40,32 @@ if test "$WITHMPICH" = yes; then
   MPICH_HOME=$withval
 
   if test "$MPICH_HOME"; then
-    MPICH_INCLUDES="-I$MPICH_HOME/include"
-    MPICH_LIBS="-L$MPICH_HOME/lib"
+    MPI_INCLUDES="-I$MPICH_HOME/include"
+    MPI_LIBS="-L$MPICH_HOME/lib"
   fi
 
   CPPFLAGS_old="$CPPFLAGS"
-  CPPFLAGS="$MPICH_INCLUDES $CPPFLAGS"
+  CPPFLAGS="$MPI_INCLUDES $CPPFLAGS"
   AC_CHECK_HEADER(mpi.h,WITHMPICH="yes",WITHMPICH="no")
   CPPFLAGS="$CPPFLAGS_old"
 
   if test "$WITHMPICH" = "yes";then
     LDFLAGS_old="$LDFLAGS"
-    LDFLAGS="$MPICH_LIBS $LDFLAGS"
+    LDFLAGS="$MPI_LIBS $LDFLAGS"
     AC_CHECK_LIB(mpich,MPI_Init,
                AC_CHECK_LIB(pmpich, PMPI_Init,WITHMPICH="yes",WITHMPICH="no"),
                WITHMPICH="no")
+    AC_CHECK_LIB(mpich,MPI_Publish_name,WITHMPI2="yes",WITHMPI2="no")
     LDFLAGS="$LDFLAGS_old"
   fi
 
-  MPICH_LIBS="$MPICH_LIBS -lpmpich -lmpich"
+  if test "$WITHMPICH" = "yes";then
+     mpi_ok=yes
+     MPI_LIBS="$MPI_LIBS -lpmpich -lmpich"
+  else
+     mpi_ok=no
+  fi
 
 fi
-AC_SUBST(MPICH_INCLUDES)
-AC_SUBST(MPICH_LIBS)
-AC_SUBST(WITHMPICH)
 
 ])dnl
index af5b5f8fa108fd63ef42ff376d95721df015cb5a..f3d5abcdb62d902211015d7a4bdc6ef2c1a10514 100644 (file)
@@ -226,7 +226,7 @@ then
   fi
 fi
 
-AC_LANG_RESTORE
+dnl AC_LANG_RESTORE
 
 AC_MSG_RESULT(for omniORBpy: $omniORBpy_ok)
 AC_MSG_RESULT(for omniORB: $omniORB_ok)
@@ -234,5 +234,68 @@ AC_MSG_RESULT(for omniORB: $omniORB_ok)
 # Save cache
 AC_CACHE_SAVE
 
+dnl AC_LANG_CPLUSPLUS
+
+CXXFLAGS_old=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $OMNIORB_CXXFLAGS $OMNIORB_INCLUDES"
+LIBS_old=$LIBS
+LIBS="$LIBS $OMNIORB_LDFLAGS $OMNIORB_LIBS"
+AC_MSG_CHECKING(whether we have double and CORBA::Double compatibility)
+AC_TRY_RUN(
+#include <stdlib.h>
+#include <CORBA.h>
+int main ()
+{
+  CORBA::Double *a=new CORBA::Double(2.5);
+  double c=2.5;
+  double *b;
+  b=(double *)a;
+
+  if( (c==*b) && (sizeof(double)==sizeof(CORBA::Double)) ){
+    delete a;
+    exit(0);
+  }
+  else{
+    delete a;
+    exit(1);
+  }
+}
+,DOUBLECOMP="yes",DOUBLECOMP="no")
+if test "$DOUBLECOMP" = yes; then
+  OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -DCOMP_CORBA_DOUBLE"
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+AC_MSG_CHECKING(whether we have int and CORBA::Long compatibility)
+AC_TRY_RUN(
+#include <stdlib.h>
+#include <CORBA.h>
+int main ()
+{
+  CORBA::Long *a=new CORBA::Long(2);
+  int c=2;
+  int *b;
+  b=(int *)a;
+
+  if( (c==*b) && (sizeof(int)==sizeof(CORBA::Long)) )
+    exit(0);
+  else
+    exit(1);
+}
+,LONGCOMP="yes",LONGCOMP="no")
+if test "$LONGCOMP" = yes; then
+  OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -DCOMP_CORBA_LONG"
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+CXXFLAGS=$CXXFLAGS_old
+LIBS=$LIBS_old
+
+AC_LANG_RESTORE
+
+AC_SUBST(OMNIORB_CXXFLAGS)
+
 ])dnl
 dnl
diff --git a/salome_adm/unix/config_files/check_sockets.m4 b/salome_adm/unix/config_files/check_sockets.m4
new file mode 100644 (file)
index 0000000..f3086ad
--- /dev/null
@@ -0,0 +1,86 @@
+AC_DEFUN([CHECK_SOCKETS],[
+
+dnl Author
+
+dnl Warren Young <warren@etr-usa.com>
+dnl M4 Source Code
+
+echo
+echo ---------------------------------------------
+echo testing sockets
+echo ---------------------------------------------
+echo
+
+AC_CACHE_CHECK(for libraries containing socket functions,
+ac_cv_socket_libs, [
+       oCFLAGS=$CFLAGS
+
+        AC_TRY_LINK([
+                        #include <sys/types.h>
+                        #include <sys/socket.h>
+                        #include <netinet/in.h>
+                        #include <arpa/inet.h>
+                ],
+                [
+                        struct in_addr add;
+                        int sd = socket(AF_INET, SOCK_STREAM, 0);
+                        inet_ntoa(add);
+                ],
+                ac_cv_socket_libs=-lc, ac_cv_socket_libs=no)
+
+        if test x"$ac_cv_socket_libs" = "xno"
+        then
+                CFLAGS="$oCFLAGS -lsocket"
+                AC_TRY_LINK([
+                                #include <sys/types.h>
+                                #include <sys/socket.h>
+                                #include <netinet/in.h>
+                                #include <arpa/inet.h>
+                        ],
+                        [
+                                struct in_addr add;
+                                int sd = socket(AF_INET, SOCK_STREAM, 0);
+                                inet_ntoa(add);
+                        ],
+                        ac_cv_socket_libs=-lsocket, ac_cv_socket_libs=no)
+        fi
+
+        if test x"$ac_cv_socket_libs" = "xno"
+        then
+                CFLAGS="$oCFLAGS -lsocket -lnsl"
+                AC_TRY_LINK([
+                                #include <sys/types.h>
+                                #include <sys/socket.h>
+                                #include <netinet/in.h>
+                                #include <arpa/inet.h>
+                        ],
+                        [
+                                struct in_addr add;
+                                int sd = socket(AF_INET, SOCK_STREAM, 0);
+                                inet_ntoa(add);
+                        ],
+                        ac_cv_socket_libs="-lsocket -lnsl", ac_cv_socket_libs=no)
+        fi
+
+        CFLAGS=$oCFLAGS
+])
+
+        if test x"$ac_cv_socket_libs" = "xno"
+        then
+                AC_MSG_ERROR([Cannot find socket libraries])
+        elif test x"$ac_cv_socket_libs" = "x-lc"
+        then
+                SOCKETLIBS=""
+                CPPFLAGS="-DHAVE_SOCKET $CPPFLAGS"
+               CORBA_IDLCXXFLAGS="-DHAVE_SOCKET $CORBA_IDLCXXFLAGS"
+               CORBA_IDLPYFLAGS="-DHAVE_SOCKET $CORBA_IDLPYFLAGS"
+        else
+                SOCKETLIBS="$ac_cv_socket_libs"
+                CPPFLAGS="-DHAVE_SOCKET $CPPFLAGS"
+               CORBA_IDLCXXFLAGS="-DHAVE_SOCKET $CORBA_IDLCXXFLAGS"
+               CORBA_IDLPYFLAGS="-DHAVE_SOCKET $CORBA_IDLPYFLAGS"
+        fi
+
+        AC_SUBST(SOCKETLIBS)
+        AC_SUBST(SOCKETFLAGS)
+]) dnl CHECK_SOCKET
index 2914ceda63c1f52fec124270a182ffcd72784921..e421712461fcbcaa5b7618253c2a51f0a87be568 100644 (file)
@@ -124,10 +124,11 @@ CAS_VIEWER=@CAS_VIEWER@
 CAS_MODELER=@CAS_MODELER@
 CAS_DATAEXCHANGE=@CAS_DATAEXCHANGE@
 CAS_LDPATH=@CAS_LDPATH@
-# MPICH
 
-MPICH_INCLUDES=@MPICH_INCLUDES@
-MPICH_LIBS=@MPICH_LIBS@
+# MPI
+
+MPI_INCLUDES=@MPI_INCLUDES@
+MPI_LIBS=@MPI_LIBS@
 
 # Swig C++ Python
 
diff --git a/src/Communication/Makefile.in b/src/Communication/Makefile.in
new file mode 100644 (file)
index 0000000..736fbe5
--- /dev/null
@@ -0,0 +1,34 @@
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl
+
+
+@COMMENCE@
+
+EXPORT_PYSCRIPTS = 
+
+EXPORT_HEADERS = \
+       ReceiverFactory.hxx \
+       SenderFactory.hxx \
+       SALOMEMultiComm.hxx \
+       MultiCommException.hxx
+# Libraries targets
+
+LIB = libSalomeCommunication.la 
+LIB_SRC = SALOME_Comm_i.cxx  SenderFactory.cxx Receiver.cxx MultiCommException.cxx SALOMEMultiComm.cxx ReceiverFactory.cxx
+LIB_SERVER_IDL = SALOME_Comm.idl SALOME_Exception.idl
+
+# Executables targets
+BIN = 
+BIN_SRC =
+BIN_SERVER_IDL = 
+
+CPPFLAGS+= $(PYTHON_INCLUDES)  $(MPI_INCLUDES) 
+
+LDFLAGS+= -lOpUtil -lSALOMELocalTrace
+
+LIBS += -Xlinker -export-dynamic $(PYTHON_LIBS) $(MPI_LIBS)
+
+@CONCLUDE@
diff --git a/src/Communication/MultiCommException.cxx b/src/Communication/MultiCommException.cxx
new file mode 100644 (file)
index 0000000..d649d96
--- /dev/null
@@ -0,0 +1,11 @@
+#include "MultiCommException.hxx"
+
+MultiCommException::MultiCommException(const char *message)
+{
+  _message=message;
+}
+
+const char *MultiCommException::what() const
+{
+  return _message.c_str();
+}
diff --git a/src/Communication/MultiCommException.hxx b/src/Communication/MultiCommException.hxx
new file mode 100644 (file)
index 0000000..0f5466c
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _MULTICOMMEXCEPTION_HXX_
+#define _MULTICOMMEXCEPTION_HXX_
+
+#include <string>
+
+using namespace std;
+
+class MultiCommException {
+private:
+  string _message;
+public:
+  MultiCommException(const char *message);
+  const char *what() const;
+};
+
+#endif
+
diff --git a/src/Communication/Receiver.cxx b/src/Communication/Receiver.cxx
new file mode 100644 (file)
index 0000000..dc24b20
--- /dev/null
@@ -0,0 +1,25 @@
+#include "Receiver.hxx"
+#include <string.h>
+
+/*!
+  return a deep copy of the array contained in the servant.
+ */
+void *Receiver::getLocalValue(long &size,SALOME_Sender_i* servant)
+{
+  const void *src=servant->getData(size);
+  long lgr=size*servant->getSizeOf();
+  void *ret=new char[lgr];
+  memcpy(ret,src,lgr);
+  return ret;
+  //return (void *)servant->getData(size);
+}
+
+void *Receiver::getValue(long &size,SALOME::Sender_ptr sender)
+{
+  SALOME_Sender_i* data=SALOME_Sender_i::find(sender);
+  if(data)
+    return getLocalValue(size,data);
+  else
+    return getDistValue(size);
+}
+
diff --git a/src/Communication/Receiver.hxx b/src/Communication/Receiver.hxx
new file mode 100644 (file)
index 0000000..56c65ad
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _RECEIVER_HXX_
+#define _RECEIVER_HXX_
+
+#include "SALOME_Comm_i.hxx"
+
+/*! Abstract class factorizing common methods of all the receivers. All of the receivers have to inheritate from it.
+ */
+class Receiver
+{
+public:
+  virtual void *getValue(long &size)=0;
+  virtual ~Receiver() {}
+protected:
+  virtual void *getValue(long &size,SALOME::Sender_ptr sender);
+  static inline void *getLocalValue(long &size,SALOME_Sender_i* servant);
+  virtual void *getDistValue(long &size)=0;
+};
+
+#endif
+
diff --git a/src/Communication/ReceiverFactory.cxx b/src/Communication/ReceiverFactory.cxx
new file mode 100644 (file)
index 0000000..31bcb67
--- /dev/null
@@ -0,0 +1,138 @@
+#include "ReceiverFactory.hxx"
+#include "Receivers.hxx"
+
+#ifdef COMP_CORBA_DOUBLE
+#define CorbaDNoCopyReceiver CorbaNCNoCopyReceiver
+#define CorbaDWithCopyReceiver CorbaNCWithCopyReceiver
+#else
+#define CorbaDNoCopyReceiver CorbaWCNoCopyReceiver
+#define CorbaDWithCopyReceiver CorbaWCWithCopyReceiver
+#endif
+
+#ifdef COMP_CORBA_LONG
+#define CorbaINoCopyReceiver CorbaNCNoCopyReceiver
+#define CorbaIWithCopyReceiver CorbaNCWithCopyReceiver
+#else
+#define CorbaINoCopyReceiver CorbaWCNoCopyReceiver
+#define CorbaIWithCopyReceiver CorbaWCWithCopyReceiver
+#endif
+
+#ifdef HAVE_SOCKET
+#include <rpc/xdr.h>
+#endif
+
+/*!
+  This method performs the transfert with the remote sender given. If it fails with this sender it tries with an another protocol (CORBA by default).
+ */
+void *ReceiverFactory::getValue(SALOME::Sender_ptr sender,long &size)throw(MultiCommException)
+{
+  void *ret;
+  try{
+    ret=getValueOneShot(sender,size);
+  }
+  catch(MultiCommException&)
+    {
+      SALOME::Sender_ptr newSender=sender->buildOtherWithProtocol(SALOME::CORBA_);
+      MESSAGE("PROTOCOL CHANGED TO CORBA");
+      sender->release();
+      CORBA::release(sender);
+      ret=getValueOneShot(newSender,size);
+    }
+  return ret;
+}
+
+/*!
+  This method performs the transfert with the remote sender given. If it fails an exception is thrown.
+ */
+void *ReceiverFactory::getValueOneShot(SALOME::Sender_ptr sender,long &size)throw(MultiCommException)
+{
+  SALOME::CorbaDoubleNCSender_ptr cncD_ptr;
+  SALOME::CorbaDoubleCSender_ptr cwcD_ptr;
+  SALOME::CorbaLongNCSender_ptr cncL_ptr;
+  SALOME::CorbaLongCSender_ptr cwcL_ptr;
+#ifdef HAVE_MPI2
+  SALOME::MPISender_ptr mpi_ptr=SALOME::MPISender::_narrow(sender);
+#endif
+#ifdef HAVE_SOCKET
+  SALOME::SocketSender_ptr sock_ptr=SALOME::SocketSender::_narrow(sender);
+#endif
+ switch(sender->getTypeOfDataTransmitted())
+    {
+    case SALOME::DOUBLE_:
+      cncD_ptr=SALOME::CorbaDoubleNCSender::_narrow(sender);
+      cwcD_ptr=SALOME::CorbaDoubleCSender::_narrow(sender);
+      if(!CORBA::is_nil(cncD_ptr))
+       {
+         CORBA::release(sender);
+         CorbaDNoCopyReceiver<double,CORBA::Double,SALOME::vectorOfDouble_var,SALOME::CorbaDoubleNCSender_ptr> rec(cncD_ptr);
+         return rec.getValue(size);
+       }
+      else if(!CORBA::is_nil(cwcD_ptr))
+       {
+         CORBA::release(sender);
+         CorbaDWithCopyReceiver<double,CORBA::Double,SALOME::vectorOfDouble_var,SALOME::CorbaDoubleCSender_ptr> rec(cwcD_ptr);
+         return rec.getValue(size);
+       }
+#ifdef HAVE_MPI2
+      else if(!CORBA::is_nil(mpi_ptr))
+       {
+         CORBA::release(sender);
+         MPIReceiver<double,MPI_DOUBLE> rec(mpi_ptr);
+         return rec.getValue(size);
+       }
+#endif
+#ifdef HAVE_SOCKET
+      else if(!CORBA::is_nil(sock_ptr))
+       {
+         CORBA::release(sender);
+         SocketReceiver<double,xdr_double> rec(sock_ptr);
+         return rec.getValue(size);
+       }
+#endif
+      else
+       {
+         throw MultiCommException("Unknown sender protocol");
+         return 0;
+       }
+    case SALOME::INT_:
+      cncL_ptr=SALOME::CorbaLongNCSender::_narrow(sender);
+      cwcL_ptr=SALOME::CorbaLongCSender::_narrow(sender);
+      if(!CORBA::is_nil(cncL_ptr))
+       {
+         CORBA::release(sender);
+         CorbaINoCopyReceiver<int,CORBA::Long,SALOME::vectorOfLong_var,SALOME::CorbaLongNCSender_ptr> rec(cncL_ptr);
+         return rec.getValue(size);
+       }
+      else if(!CORBA::is_nil(cwcL_ptr))
+       {
+         CORBA::release(sender);
+         CorbaIWithCopyReceiver<int,CORBA::Long,SALOME::vectorOfLong_var,SALOME::CorbaLongCSender_ptr> rec(cwcL_ptr);
+         return rec.getValue(size);
+       }
+#ifdef HAVE_MPI2
+      else if(!CORBA::is_nil(mpi_ptr))
+       {
+         CORBA::release(sender);
+         MPIReceiver<int,MPI_INT> rec(mpi_ptr);
+         return rec.getValue(size);
+       }
+#endif
+#ifdef HAVE_SOCKET
+      else if(!CORBA::is_nil(sock_ptr))
+       {
+         CORBA::release(sender);
+         SocketReceiver<int,xdr_int> rec(sock_ptr);
+         return rec.getValue(size);
+       }
+#endif
+      else
+       {
+         throw MultiCommException("Unknown sender protocol");
+         return 0;
+       }
+    default:
+      throw MultiCommException("unknown type of data transfered");
+      return 0;
+    }
+}
+
diff --git a/src/Communication/ReceiverFactory.hxx b/src/Communication/ReceiverFactory.hxx
new file mode 100644 (file)
index 0000000..e5072c9
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _RECEIVERFACTORY_HXX_
+#define _RECEIVERFACTORY_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOME_Comm)
+#include "MultiCommException.hxx"
+
+/*!
+  This class internally builds a receiver associated with the sender given. It also performs transfert completely and clean up the objects.
+  This is the only class used client side of an array.
+ */
+class ReceiverFactory
+{
+public:
+  static void *getValue(SALOME::Sender_ptr sender,long &size)throw(MultiCommException);
+private:
+  static void *getValueOneShot(SALOME::Sender_ptr sender,long &size)throw(MultiCommException);
+};
+
+#endif
+
diff --git a/src/Communication/Receivers.cxx b/src/Communication/Receivers.cxx
new file mode 100644 (file)
index 0000000..e01125a
--- /dev/null
@@ -0,0 +1,390 @@
+#include "poa.h"
+#include "utilities.h"
+
+#define TAILLE_SPLIT 100000
+#define TIMEOUT 20
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+CorbaNCNoCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::CorbaNCNoCopyReceiver(CorbaSender mySender):_mySender(mySender){
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+CorbaNCNoCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::~CorbaNCNoCopyReceiver(){
+  _mySender->release();
+  CORBA::release(_mySender);
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+void *CorbaNCNoCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::getDistValue(long &size)
+{
+  TSeqCorba seq=_mySender->send();
+  size=seq->length();
+  return seq->get_buffer(1);
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+void *CorbaNCNoCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::getValue(long &size)
+{
+  return Receiver::getValue(size,_mySender);
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+CorbaNCWithCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::CorbaNCWithCopyReceiver(CorbaSender mySender):_mySender(mySender){
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+CorbaNCWithCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::~CorbaNCWithCopyReceiver(){
+  _mySender->release();
+  CORBA::release(_mySender);
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+void *CorbaNCWithCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::getDistValue(long &size){
+  size=_mySender->getSize();
+  long n;
+  T *ret=new T[size];
+  T *iter=ret;
+  for(long i=0;i<size;i+=TAILLE_SPLIT)
+    {
+      if(size-i>TAILLE_SPLIT)
+       n=TAILLE_SPLIT;
+      else
+       n=size-i;
+      TSeqCorba seq=_mySender->sendPart(i,n);
+      T *seqd=(T *)seq->get_buffer(0);
+      for(long j=0;j<n;j++)
+       *iter++=*seqd++;
+    }
+  return ret;
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+void *CorbaNCWithCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::getValue(long &size)
+{
+  return Receiver::getValue(size,_mySender);
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+CorbaWCNoCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::CorbaWCNoCopyReceiver(CorbaSender mySender):_mySender(mySender){
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+CorbaWCNoCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::~CorbaWCNoCopyReceiver(){
+  _mySender->release();
+  CORBA::release(_mySender);
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+void *CorbaWCNoCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::getDistValue(long &size){
+  size=_mySender->getSize();
+  long n;
+  T *ret=new T[size];
+  T *iter=ret;
+  for(long i=0;i<size;i+=TAILLE_SPLIT)
+    {
+      if(size-i>TAILLE_SPLIT)
+       n=TAILLE_SPLIT;
+      else
+       n=size-i;
+      TSeqCorba seq=_mySender->sendPart(i,n);
+      TCorba *seqd=seq->get_buffer(0);
+      for(long j=0;j<n;j++)
+       *iter++=*seqd++;
+    }
+  return ret;
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+void *CorbaWCNoCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::getValue(long &size)
+{
+  return Receiver::getValue(size,_mySender);
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+CorbaWCWithCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::CorbaWCWithCopyReceiver(CorbaSender mySender):_mySender(mySender){
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+CorbaWCWithCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::~CorbaWCWithCopyReceiver(){
+  _mySender->release();
+  CORBA::release(_mySender);
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+void *CorbaWCWithCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::getDistValue(long &size){
+  size=_mySender->getSize();
+  long n;
+  T *ret=new T[size];
+  T *iter=ret;
+  for(long i=0;i<size;i+=TAILLE_SPLIT)
+    {
+      if(size-i>TAILLE_SPLIT)
+       n=TAILLE_SPLIT;
+      else
+       n=size-i;
+      TSeqCorba seq=_mySender->sendPart(i,n);
+      TCorba *seqd=seq->get_buffer(0);
+      for(long j=0;j<n;j++)
+      *iter++=*seqd++;
+    }
+  return ret;
+}
+
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+void *CorbaWCWithCopyReceiver<T,TCorba,TSeqCorba,CorbaSender>::getValue(long &size)
+{
+  return Receiver::getValue(size,_mySender);
+}
+
+#ifdef HAVE_MPI2
+
+template<class T,MPI_Datatype T2>
+MPIReceiver<T,T2>::MPIReceiver(SALOME::MPISender_ptr mySender):_mySender(mySender){
+}
+
+template<class T,MPI_Datatype T2>
+MPIReceiver<T,T2>::~MPIReceiver(){
+  _mySender->release();
+  CORBA::release(_mySender);
+}
+
+template<class T,MPI_Datatype T2>
+void *MPIReceiver<T,T2>::getDistValue(long &size){
+  int i=0;
+  int myproc;
+  int sproc;
+  MPI_Status status;
+  MPI_Comm com; 
+  char   port_name_clt [MPI_MAX_PORT_NAME];
+  float telps, tuser, tsys, tcpu;
+  T *_v;
+  long _n;
+
+  
+  CORBA::Any a; 
+  MPI_Comm_rank(MPI_COMM_WORLD, &myproc);
+  SALOME::MPISender::param_var p =_mySender->getParam();
+  _mySender->send();
+  sproc = p->myproc;
+  MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
+  while ( i != TIMEOUT  && MPI_Lookup_name((char*)p->service,MPI_INFO_NULL,port_name_clt) != MPI_SUCCESS) { 
+    i++;
+  }       
+  MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
+  if ( i == TIMEOUT  ) { 
+    MPI_Finalize();
+    exit(-1);
+  }
+  else{
+    //       Connect to service, get the inter-communicator server
+    //      Attention MPI_Comm_connect est un appel collectif :
+    //         - Si lancement mpirun -c n -----> uniquement     MPI_COMM_SELF fonctionne
+    //         - Si lancement client_server&client_server ----> MPI_COMM_WORLD fonctionne
+    
+    //      TIMEOUT is inefficient since MPI_Comm_Connect doesn't return if we asked for
+    //        a service that has been unpublished !
+    MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
+    i = 0;
+    while ( i != TIMEOUT  &&  MPI_Comm_connect(port_name_clt, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &com)!=MPI_SUCCESS ) { 
+      i++; 
+    } 
+    MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
+    if ( i == TIMEOUT ) {
+      MPI_Finalize(); 
+      exit(-1);
+    }
+  }
+  MPI_Recv( &_n, 1, MPI_LONG, sproc,p->tag1,com,&status);
+  _v = new T[_n];
+  MPI_Recv( _v, _n, T2, sproc,p->tag2,com,&status);
+  _mySender->close(p);
+  MPI_Comm_disconnect( &com );  
+  size=_n;
+  return _v;
+}
+
+template<class T,MPI_Datatype T2>
+void *MPIReceiver<T,T2>::getValue(long &size)
+{
+  return Receiver::getValue(size,_mySender);
+}
+
+#endif
+
+#ifdef HAVE_SOCKET
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <rpc/xdr.h>
+
+template<class T,int (*myFunc)(XDR*,T*)>
+SocketReceiver<T,myFunc>::SocketReceiver(SALOME::SocketSender_ptr mySender) : _mySender(mySender)
+{
+  _clientSockfd = -1;
+  _senderDestruc=true;
+}
+
+template<class T,int (*myFunc)(XDR*,T*)>
+SocketReceiver<T,myFunc>::~SocketReceiver()
+{
+  if(_senderDestruc)
+    {
+      _mySender->release();
+      CORBA::release(_mySender);
+    }
+}
+
+template<class T,int (*myFunc)(XDR*,T*)>
+void *SocketReceiver<T,myFunc>::getValue(long &size)
+{
+  return Receiver::getValue(size,_mySender);
+}
+
+template<class T,int (*myFunc)(XDR*,T*)>
+void* SocketReceiver<T,myFunc>::getDistValue(long &size)
+{
+  int n=0, m;
+  T *v;
+  XDR xp; /* pointeur sur le decodeur XDR */
+
+  try{
+    initCom();
+
+    SALOME::SocketSender::param_var p = _mySender->getParam();
+
+    size = p->lend - p->lstart + 1;
+    v = new T[size];
+
+    connectCom(p->internet_address, p->myport);
+  
+    _mySender->send();
+
+    xdrmem_create(&xp,(char*)v,size*sizeof(T),XDR_DECODE );
+    while( n < size*sizeof(T) ){
+      m = read(_clientSockfd, (char*)v+n, size*sizeof(T)-n);
+      if( m < 0 ){
+       closeCom();
+       delete [] v;
+       SALOME::ExceptionStruct es;
+       es.type = SALOME::COMM;
+       es.text = "error read Socket exception";
+       throw SALOME::SALOME_Exception(es);
+      }
+      n += m;
+    }
+    xdr_vector( &xp, (char*)v, size, sizeof(T), (xdrproc_t)myFunc);
+    xdr_destroy( &xp );
+    
+    _mySender->endOfCom();
+    closeCom();
+  }
+  catch(SALOME::SALOME_Exception &ex){
+    if( ex.details.type == SALOME::COMM )
+      {
+       _senderDestruc=false;
+       cout << ex.details.text << endl;
+       throw MultiCommException("Unknown sender protocol");
+      }
+    else
+      throw ex;
+  }
+  return v;
+}
+
+template<class T,int (*myFunc)(XDR*,T*)>
+void SocketReceiver<T,myFunc>::initCom()
+{
+  try{
+    _mySender->initCom();
+
+    /* Ouverture de la socket */
+    _clientSockfd = socket(AF_INET, SOCK_STREAM, 0);
+    if (_clientSockfd < 0) {
+      closeCom();
+      SALOME::ExceptionStruct es;
+      es.type = SALOME::COMM;
+      es.text = "error Socket exception";
+      throw SALOME::SALOME_Exception(es);
+    }
+  }
+  catch(SALOME::SALOME_Exception &ex){
+    if( ex.details.type == SALOME::COMM )
+      {
+       _senderDestruc=false;
+       cout << ex.details.text << endl;
+       throw MultiCommException("Unknown sender protocol");
+      }
+    else
+      throw ex;
+  }
+
+}
+
+template<class T,int (*myFunc)(XDR*,T*)>
+void SocketReceiver<T,myFunc>::connectCom(const char *dest_address, int port)
+{
+  struct sockaddr_in serv_addr;
+  struct hostent * server;
+  SALOME::ExceptionStruct es;
+
+  try{
+    /* reception of the host structure on the remote process */
+    server = gethostbyname(dest_address);
+    if( server == NULL ) {
+      closeCom();
+      es.type = SALOME::COMM;
+      es.text = "error unknown host Socket exception";
+      _senderDestruc=false;
+      throw SALOME::SALOME_Exception(es);
+    }
+
+    /* Initialisation of the socket structure */
+    bzero((char*)&serv_addr,sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_addr.s_addr = INADDR_ANY;
+    bcopy((char *)server->h_addr, 
+         (char *)&serv_addr.sin_addr.s_addr,
+         server->h_length);
+    serv_addr.sin_port = htons(port);
+    
+    if( connect(_clientSockfd, (struct sockaddr *) & serv_addr, sizeof(struct sockaddr)) < 0 ){
+      closeCom();
+      es.type = SALOME::COMM;
+      es.text = "error connect Socket exception";
+      _senderDestruc=false;
+      throw SALOME::SALOME_Exception(es);
+    }
+
+    _mySender->acceptCom();
+
+  }
+  catch(SALOME::SALOME_Exception &ex){
+    if( ex.details.type == SALOME::COMM )
+      {
+       _senderDestruc=false;
+       cout << ex.details.text << endl;
+       throw MultiCommException("Unknown sender protocol");
+      }
+    else
+      throw ex;
+  }
+
+}
+
+
+template<class T,int (*myFunc)(XDR*,T*)>
+void SocketReceiver<T,myFunc>::closeCom()
+{
+  _mySender->closeCom();
+  if( _clientSockfd >= 0 ){
+    close(_clientSockfd);
+    _clientSockfd = -1;
+  }
+}
+
+#endif
diff --git a/src/Communication/Receivers.hxx b/src/Communication/Receivers.hxx
new file mode 100644 (file)
index 0000000..4fd2581
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef _RECEIVERS_HXX_
+#define _RECEIVERS_HXX_
+
+#include "SALOME_Comm_i.hxx"
+#include "Receiver.hxx"
+#ifdef HAVE_MPI2
+#include "mpi.h"
+#endif
+
+/*!
+  Receiver used for transfert with CORBA when no copy is required remotely and locally.
+ */
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+class CorbaNCNoCopyReceiver : public Receiver
+{
+private:
+  CorbaSender _mySender;
+public:
+  CorbaNCNoCopyReceiver(CorbaSender mySender);
+  ~CorbaNCNoCopyReceiver();
+  void *getValue(long &size);
+private:
+  void *getDistValue(long &size);
+};
+
+/*!
+  Receiver used for transfert with CORBA when copy is not required remotely but required locally.
+ */
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+class CorbaNCWithCopyReceiver : public Receiver
+{
+private:
+  CorbaSender _mySender;
+public:
+  CorbaNCWithCopyReceiver(CorbaSender mySender);
+  ~CorbaNCWithCopyReceiver();
+  void *getValue(long &size);
+private:
+  void *getDistValue(long &size);
+};
+
+/*!
+  Receiver used for transfert with CORBA when copy is required remotely but not required locally.
+ */
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+class CorbaWCNoCopyReceiver : public Receiver
+{
+private:
+  CorbaSender  _mySender;
+public:
+  CorbaWCNoCopyReceiver(CorbaSender mySender);
+  ~CorbaWCNoCopyReceiver();
+  void *getValue(long &size);
+private:
+  void *getDistValue(long &size);
+};
+
+/*!
+  Receiver used for transfert with CORBA when copy is required both remotely and locally.
+ */
+template<class T,class TCorba,class TSeqCorba,class CorbaSender>
+class CorbaWCWithCopyReceiver : public Receiver
+{
+private:
+  CorbaSender _mySender;
+public:
+  CorbaWCWithCopyReceiver(CorbaSender mySender);
+  ~CorbaWCWithCopyReceiver();
+  void *getValue(long &size);
+private:
+  void *getDistValue(long &size);
+};
+
+#ifdef HAVE_MPI2
+/*!
+  Receiver for MPI transfert.
+ */
+template<class T,MPI_Datatype T2>
+class MPIReceiver : public Receiver
+{
+private:
+  SALOME::MPISender_ptr _mySender;
+public:
+  MPIReceiver(SALOME::MPISender_ptr mySender);
+  ~MPIReceiver();
+  void *getValue(long &size);
+private:
+  void *getDistValue(long &size);
+};
+#endif
+
+#ifdef HAVE_SOCKET
+
+class XDR;
+
+/*!
+  Receiver for transfert with sockets.
+ */
+template<class T,int (*myFunc)(XDR*,T*)>
+class SocketReceiver : public Receiver
+{
+private:
+  SALOME::SocketSender_ptr _mySender;
+  int _clientSockfd;
+  bool _senderDestruc;
+public:
+  SocketReceiver(SALOME::SocketSender_ptr mySender);
+  ~SocketReceiver();
+  void *getValue(long &size);
+private:
+  void *getDistValue(long &size);
+  void initCom();
+  void connectCom(const char *, int);
+  void closeCom();
+};
+#endif
+
+#include "Receivers.cxx"
+
+#endif
+
diff --git a/src/Communication/SALOMEMultiComm.cxx b/src/Communication/SALOMEMultiComm.cxx
new file mode 100644 (file)
index 0000000..71c4135
--- /dev/null
@@ -0,0 +1,21 @@
+#include "SALOMEMultiComm.hxx"
+
+SALOMEMultiComm::SALOMEMultiComm():_type(SALOME::CORBA_)
+{
+}
+
+SALOMEMultiComm::SALOMEMultiComm(SALOME::TypeOfCommunication type):_type(type)
+{
+}
+
+void SALOMEMultiComm::setProtocol(SALOME::TypeOfCommunication type)
+{
+  _type=type;
+}
+
+SALOME::TypeOfCommunication SALOMEMultiComm::getProtocol() const
+{
+  return _type;
+}
+
+
diff --git a/src/Communication/SALOMEMultiComm.hxx b/src/Communication/SALOMEMultiComm.hxx
new file mode 100644 (file)
index 0000000..2537dc0
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _SALOMEMULTICOMM_HXX_
+#define _SALOMEMULTICOMM_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOME_Comm)
+
+/*!
+  Class is designed to ease the use of multi communication.\n
+  Simply inherite from it your servant class you want to emit data with senders.
+ */
+class SALOMEMultiComm : public virtual POA_SALOME::MultiCommClass {
+protected:
+  SALOME::TypeOfCommunication _type;
+public:
+  SALOMEMultiComm();
+  SALOMEMultiComm(SALOME::TypeOfCommunication type);
+  virtual void setProtocol(SALOME::TypeOfCommunication type);
+  SALOME::TypeOfCommunication getProtocol() const;
+};
+
+#endif
diff --git a/src/Communication/SALOME_Comm_i.cxx b/src/Communication/SALOME_Comm_i.cxx
new file mode 100644 (file)
index 0000000..00fe36a
--- /dev/null
@@ -0,0 +1,483 @@
+#include <rpc/xdr.h>
+#include "SALOME_Comm_i.hxx"
+#include "poa.h"
+#include "omnithread.h"
+#include "Utils_SINGLETON.hxx"
+#include "Utils_ORB_INIT.hxx"
+#include "utilities.h"
+
+#include "SenderFactory.hxx"
+
+CORBA::ORB_var &getGlobalORB(){
+  ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance();
+  CORBA::ORB_var &orb = init(0,0);
+  return orb;
+}
+
+/*! Return the C++ data associated to the array to transmit.
+  Used when sender and receiver are collocalized.
+ */
+const void *SALOME_Sender_i::getData(long &size) const{
+  size=_lgrTabToSend;
+  return _tabToSend;
+}
+
+/*! Return the sizeof() of each component of the generic array
+ */
+int SALOME_Sender_i::getSizeOf() const {
+  return _sizeOf;
+}
+
+/*! Unique constructor */
+SALOME_Sender_i::SALOME_Sender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf):_tabToSend(tabToSend),_lgrTabToSend(lgrTabToSend),_type(type),_sizeOf(sizeOf){
+}
+
+/*! Method to establish if the CORBA object refered by pCorba is collocalised.\n
+  If it is, the pointer to the servant that incarnates the CORBA object is returned.
+*/
+SALOME_Sender_i *SALOME_Sender_i::find(SALOME::Sender_ptr pCorba){
+  PortableServer::ServantBase *ret;
+  try {
+    ret=PortableServer::POA::_the_root_poa()->reference_to_servant(pCorba);
+  }
+  catch(...){
+    return 0;
+  }
+  ret->_remove_ref();
+  return dynamic_cast<SALOME_Sender_i *>(ret);
+}
+
+/*! Method for the remote destroy of the current servant. This method is used by the receiver to destroy the sender when the transfert is complete.
+ */
+void SALOME_Sender_i::release()
+{
+  PortableServer::ObjectId_var oid = _default_POA()->servant_to_id(this);
+  _default_POA()->deactivate_object(oid);
+  _remove_ref();
+}
+
+/*! Return the type of the element that compose the array. Used by receiverfactory to build the correct receiver.
+ */
+SALOME::TypeOfDataTransmitted SALOME_Sender_i::getTypeOfDataTransmitted()
+{
+  return _type;
+}
+
+/*! Return a new sender of the same array but with an another protocol.
+ */
+SALOME::Sender_ptr SALOME_Sender_i::buildOtherWithProtocol(SALOME::TypeOfCommunication type)
+{
+  return SenderFactory::buildSender(type,this);
+}
+
+SALOME_CorbaDoubleNCSender_i::SALOME_CorbaDoubleNCSender_i(const double *tabToSend,long lgrTabToSend):SALOME_Sender_i(SALOME::DOUBLE_,tabToSend,lgrTabToSend,sizeof(double)){
+}
+
+SALOME_CorbaDoubleNCSender_i::~SALOME_CorbaDoubleNCSender_i(){
+}
+
+CORBA::ULong SALOME_CorbaDoubleNCSender_i::getSize(){
+  CORBA::ULong ret=_lgrTabToSend;
+  return ret;
+}
+
+SALOME::vectorOfDouble* SALOME_CorbaDoubleNCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
+  SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble(length,length,(CORBA::Double *)((double *)_tabToSend+(long)offset),0);
+  return c1._retn();
+}
+
+SALOME::vectorOfDouble* SALOME_CorbaDoubleNCSender_i::send(){
+  SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble(_lgrTabToSend,_lgrTabToSend,(CORBA::Double *)_tabToSend,0);
+  return c1._retn();
+}
+
+SALOME_CorbaDoubleCSender_i::SALOME_CorbaDoubleCSender_i(const double *tabToSend,long lgrTabToSend):SALOME_Sender_i(SALOME::DOUBLE_,tabToSend,lgrTabToSend,sizeof(double)){
+}
+
+SALOME_CorbaDoubleCSender_i::~SALOME_CorbaDoubleCSender_i(){
+}
+
+CORBA::ULong SALOME_CorbaDoubleCSender_i::getSize(){
+  CORBA::ULong ret=_lgrTabToSend;
+  return ret;
+}
+
+SALOME::vectorOfDouble* SALOME_CorbaDoubleCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
+  SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble;
+  c1->length(length);
+  for (long i=0; i<length; i++)
+    c1[i] = ((double *)_tabToSend)[i+offset];
+  return c1._retn();
+}
+
+////////////////////////
+
+SALOME_CorbaLongNCSender_i::SALOME_CorbaLongNCSender_i(const int *tabToSend,long lgrTabToSend):SALOME_Sender_i(SALOME::INT_,tabToSend,lgrTabToSend,sizeof(int)){
+}
+
+SALOME_CorbaLongNCSender_i::~SALOME_CorbaLongNCSender_i(){
+}
+
+CORBA::ULong SALOME_CorbaLongNCSender_i::getSize(){
+  CORBA::ULong ret=_lgrTabToSend;
+  return ret;
+}
+
+SALOME::vectorOfLong* SALOME_CorbaLongNCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
+  SALOME::vectorOfLong_var c1 = new SALOME::vectorOfLong(length,length,(CORBA::Long *)((long *)_tabToSend+(long)offset),0);
+  return c1._retn();
+}
+
+SALOME::vectorOfLong* SALOME_CorbaLongNCSender_i::send(){
+  SALOME::vectorOfLong_var c1 = new SALOME::vectorOfLong(_lgrTabToSend,_lgrTabToSend,(CORBA::Long *)_tabToSend,0);
+  return c1._retn();
+}
+
+SALOME_CorbaLongCSender_i::SALOME_CorbaLongCSender_i(const int *tabToSend,long lgrTabToSend):SALOME_Sender_i(SALOME::INT_,tabToSend,lgrTabToSend,sizeof(int)){
+}
+
+SALOME_CorbaLongCSender_i::~SALOME_CorbaLongCSender_i(){
+}
+
+CORBA::ULong SALOME_CorbaLongCSender_i::getSize(){
+  CORBA::ULong ret=_lgrTabToSend;
+  return ret;
+}
+
+SALOME::vectorOfLong* SALOME_CorbaLongCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
+  SALOME::vectorOfLong_var c1 = new SALOME::vectorOfLong;
+  c1->length(length);
+  for (long i=0; i<length; i++)
+    c1[i] = ((long *)_tabToSend)[i+offset];
+  return c1._retn();
+}
+
+#ifdef HAVE_MPI2
+
+unsigned long SALOME_MPISender_i::_tag1=0;
+
+unsigned long SALOME_MPISender_i::_tag2=1;
+
+SALOME_MPISender_i::SALOME_MPISender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf):SALOME_Sender_i(type,tabToSend,lgrTabToSend,sizeOf){
+  _portName=new char[MPI_MAX_PORT_NAME];
+}
+
+SALOME_MPISender_i::~SALOME_MPISender_i(){
+  delete [] _portName;
+}
+
+SALOME::MPISender::param* SALOME_MPISender_i::getParam()
+{
+  char stag[12];
+  int myproc,i=0;
+
+  SALOME::MPISender::param_var p = new SALOME::MPISender::param;
+  MPI_Comm_rank(MPI_COMM_WORLD,&_cproc);
+  p->myproc = _cproc;
+  p->tag1 = _tag1;
+  _tag1Inst=_tag1;
+  p->tag2 =_tag2;
+  _tag2Inst=_tag2;
+  std::string service("toto_");
+  sprintf(stag,"%d_",_tag1);
+  service += stag;
+  sprintf(stag,"%d_",p->tag2);
+  service += stag;
+  p->service = CORBA::string_dup(service.c_str());
+  MPI_Open_port(MPI_INFO_NULL, _portName);
+  MPI_Errhandler_set(MPI_COMM_WORLD,MPI_ERRORS_RETURN);
+  while ( i != TIMEOUT  && MPI_Publish_name((char*)service.c_str(),MPI_INFO_NULL,_portName) != MPI_SUCCESS) {
+    i++;
+  } 
+  MPI_Errhandler_set(MPI_COMM_WORLD,MPI_ERRORS_ARE_FATAL);
+  if ( i == TIMEOUT  ) { 
+    MPI_Close_port(_portName);
+    MPI_Finalize();
+    exit(-1);
+    }
+  _tag1 += 2;
+  _tag2 += 2;
+  return p._retn();
+}
+
+void SALOME_MPISender_i::send()
+{
+  _argsForThr=new (void *)[8];
+  _argsForThr[0]=_portName;
+  _argsForThr[1]=&_lgrTabToSend;
+  _argsForThr[2]=(void *)_tabToSend;
+  _argsForThr[3]=&_cproc;
+  _argsForThr[4]=&_tag1Inst;
+  _argsForThr[5]=&_tag2Inst;
+  _argsForThr[6]=&_com;
+  _argsForThr[7]=&_type;
+
+  _newThr=new omni_thread(SALOME_MPISender_i::myThread,_argsForThr);
+  _newThr->start();
+}
+
+void* SALOME_MPISender_i::myThread(void *args)
+{
+  void **argsTab=(void **)args;
+  long *lgrTabToSend=(long *)argsTab[1];
+  int *cproc=(int *)argsTab[3];
+  int *tag1=(int *)argsTab[4];
+  int *tag2=(int *)argsTab[5];
+  MPI_Comm *com=(MPI_Comm *)argsTab[6];
+  SALOME::TypeOfDataTransmitted *type=(SALOME::TypeOfDataTransmitted *)argsTab[7];
+
+  MPI_Comm_accept((char *)argsTab[0],MPI_INFO_NULL,0,MPI_COMM_SELF,com);
+  MPI_Send(lgrTabToSend,1,MPI_LONG,*cproc,*tag1,*com);
+  switch(*type)
+    { 
+    case SALOME::DOUBLE_:
+      MPI_Send(argsTab[2],*lgrTabToSend,MPI_DOUBLE,*cproc,*tag2,*com);
+      break;
+    case SALOME::INT_:
+      MPI_Send(argsTab[2],*lgrTabToSend,MPI_INT,*cproc,*tag2,*com);
+    }
+  omni_thread::exit();
+}
+
+void SALOME_MPISender_i::close(const SALOME::MPISender::param& p)
+{
+  std::string service(p.service);
+  const char *st=p.service;
+  void *r;
+  _newThr->join(&r);
+  MPI_Comm_free(&_com); 
+  MPI_Unpublish_name((char *)service.c_str(),MPI_INFO_NULL,_portName); 
+  MPI_Close_port(_portName);
+  delete [] _argsForThr;
+}
+
+#endif
+
+#ifdef HAVE_SOCKET
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+
+SALOME_SocketSender_i::SALOME_SocketSender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf):SALOME_Sender_i(type,tabToSend,lgrTabToSend,sizeOf){
+  _IPAddress = inetAddress();
+  _serverSockfd = -1;
+  _clientSockfd = -1;
+}
+
+SALOME_SocketSender_i::~SALOME_SocketSender_i(){
+}
+
+std::string SALOME_SocketSender_i::inetAddress()
+{
+   char s[256];
+   char t[INET_ADDRSTRLEN+1];
+   struct hostent *host;
+   struct in_addr saddr;
+
+   gethostname(s, 255);
+
+   *t = '\0';
+
+   saddr.s_addr = inet_addr(s);
+   if (saddr.s_addr != -1)
+      inet_ntop(AF_INET, &saddr, t, INET_ADDRSTRLEN);
+   else {
+      host = gethostbyname(s);
+      if (host != NULL)
+         inet_ntop(AF_INET, (struct in_addr *) *host->h_addr_list, 
+                  t, INET_ADDRSTRLEN);
+   }
+   return std::string(t);
+}
+
+SALOME::SocketSender::param * SALOME_SocketSender_i::getParam()
+{
+
+  SALOME::SocketSender::param_var p = new SALOME::SocketSender::param;
+
+  p->lstart = 0;
+  p->lend = _lgrTabToSend - 1;
+  p->myport = _port;
+  p->internet_address = CORBA::string_dup(_IPAddress.c_str());
+
+  return p._retn();
+}
+
+void SALOME_SocketSender_i::send()
+{
+  _argsForThr=new void *[6];
+  _argsForThr[0]=&_serverSockfd;
+  _argsForThr[1]=&_clientSockfd;
+  _argsForThr[2]=&_lgrTabToSend;
+  _argsForThr[3]=(void *)_tabToSend;
+  _argsForThr[4]=&_errorFlag;
+  _argsForThr[5]=&_type;
+
+  _newThr=new omni_thread(SALOME_SocketSender_i::myThread,_argsForThr);
+  _newThr->start();
+}
+
+void* SALOME_SocketSender_i::myThread(void *args)
+{
+  int n=0, m;
+  void **argsTab=(void **)args;
+  int *serverSockfd=(int *)argsTab[0];
+  int *clientSockfd=(int *)argsTab[1];
+  long *lgrTabToSend=(long *)argsTab[2];
+  void *tabToSend=argsTab[3];
+  bool *errorFlag=(bool*)argsTab[4];
+  SALOME::TypeOfDataTransmitted *type=(SALOME::TypeOfDataTransmitted *)argsTab[5];
+  
+  XDR xp; /* pointeur sur le decodeur XDR */
+  
+  switch(*type)
+    { 
+    case SALOME::DOUBLE_:
+      xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(double),XDR_ENCODE );
+      xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(double), (xdrproc_t)xdr_double );
+
+      *errorFlag = false;
+      while( n < *lgrTabToSend*sizeof(double) ){
+       m = write(*clientSockfd, (char*)tabToSend+n, *lgrTabToSend*sizeof(double)-n);
+       if( m < 0 ){
+         if( *clientSockfd >= 0 ){
+           ::close(*clientSockfd);
+           *clientSockfd = -1;
+         }
+         if( *serverSockfd >= 0 ){
+           ::close(*serverSockfd);
+           *serverSockfd = -1;
+         }
+         *errorFlag = true;
+       }
+       n += m;
+      }
+      xdr_destroy( &xp );
+
+      xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(double),XDR_DECODE );
+      xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(double), (xdrproc_t)xdr_double );
+      xdr_destroy( &xp );
+      break;
+    case SALOME::INT_:
+      xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(int),XDR_ENCODE );
+      xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(int), (xdrproc_t)xdr_int );
+
+      *errorFlag = false;
+      while( n < *lgrTabToSend*sizeof(int) ){
+       m = write(*clientSockfd, (char*)tabToSend+n, *lgrTabToSend*sizeof(int)-n);
+       if( m < 0 ){
+         if( *clientSockfd >= 0 ){
+           ::close(*clientSockfd);
+           *clientSockfd = -1;
+         }
+         if( *serverSockfd >= 0 ){
+           ::close(*serverSockfd);
+           *serverSockfd = -1;
+         }
+         *errorFlag = true;
+       }
+       n += m;
+      }
+      xdr_destroy( &xp );
+
+      xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(int),XDR_DECODE );
+      xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(int), (xdrproc_t)xdr_int );
+      xdr_destroy( &xp );
+    }
+}
+
+void SALOME_SocketSender_i::initCom() throw(SALOME::SALOME_Exception)
+{
+  struct sockaddr_in serv_addr;
+  socklen_t n;
+  SALOME::ExceptionStruct es;
+
+  /* Ouverture de la socket */
+  _serverSockfd = socket(AF_INET , SOCK_STREAM , 0);
+  if(_serverSockfd < 0) {
+    es.type = SALOME::COMM;
+    es.text = "error Socket exception";
+    throw SALOME::SALOME_Exception(es);
+  }
+  /* Socket structure initialisation*/
+  bzero((char*)&serv_addr,sizeof(serv_addr));
+  serv_addr.sin_family = AF_INET;
+  serv_addr.sin_port = 0; /* asking for a free port */
+  serv_addr.sin_addr.s_addr = INADDR_ANY;
+
+  /* Association of socket with a port */
+  if( ::bind(_serverSockfd, (struct sockaddr *) & serv_addr, 
+          sizeof(struct sockaddr)) < 0 ) {
+    closeCom();
+    es.type = SALOME::COMM;
+    es.text = "error bind Socket exception";
+    throw SALOME::SALOME_Exception(es);
+  }
+  /* Listening to the allocated port */
+  if( listen(_serverSockfd, 10) < 0 ) {
+    closeCom();
+    es.type = SALOME::COMM;
+    es.text = "error listen Socket exception";
+    throw SALOME::SALOME_Exception(es);
+  }
+  /* Retrieving port number*/
+  if( getsockname(_serverSockfd, (struct sockaddr *) & serv_addr, &n) < 0 ){
+    closeCom();
+    es.type = SALOME::COMM;
+    es.text = "error getName Socket exception";
+    throw SALOME::SALOME_Exception(es);
+  }
+  _port = htons(serv_addr.sin_port);
+  SCRUTE(_port);
+}
+
+void SALOME_SocketSender_i::acceptCom() throw(SALOME::SALOME_Exception)
+{
+  socklen_t sin_size;
+  int new_fd;
+  struct sockaddr_in client_addr;
+  SALOME::ExceptionStruct es;
+
+  sin_size = sizeof(struct sockaddr_in);
+  
+  _clientSockfd = accept(_serverSockfd, (struct sockaddr *)&client_addr, &sin_size);
+  if( _clientSockfd < 0 ){
+    closeCom();
+    es.type = SALOME::COMM;
+    es.text = "error accept Socket exception";
+    throw SALOME::SALOME_Exception(es);
+  }
+}
+
+void SALOME_SocketSender_i::closeCom()
+{
+  if( _clientSockfd >= 0 ){
+    ::close(_clientSockfd);
+    _clientSockfd = -1;
+  }
+  if( _serverSockfd >= 0 ){
+    ::close(_serverSockfd);
+    _serverSockfd = -1;
+  }
+
+}
+
+void SALOME_SocketSender_i::endOfCom()
+{
+  void *r;
+  _newThr->join(&r);
+  if(_errorFlag)
+    {
+      SALOME::ExceptionStruct es;
+      es.type = SALOME::COMM;
+      es.text = "error write Socket exception";
+      throw SALOME::SALOME_Exception(es);
+    }
+  delete [] _argsForThr;
+}
+
+#endif
diff --git a/src/Communication/SALOME_Comm_i.hxx b/src/Communication/SALOME_Comm_i.hxx
new file mode 100644 (file)
index 0000000..6a8c23b
--- /dev/null
@@ -0,0 +1,162 @@
+#ifndef _SALOME_COMM_I_HXX_
+#define _SALOME_COMM_I_HXX_
+
+#include <set.h>
+#include <string>
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOME_Comm)
+#ifdef HAVE_MPI2
+#include "mpi.h"
+#endif
+
+#define TIMEOUT 20
+
+using namespace std;
+
+/*!
+  Generic servant class for senders that factorizes all the common methods and attributes necessary to senders.
+  All servant classes for senders have to inheritate from it.
+ */
+class SALOME_Sender_i : public virtual POA_SALOME::Sender,
+                       public PortableServer::RefCountServantBase {
+protected:
+  /*! Pointer to the generic array to transmit*/
+  const void *_tabToSend;
+  /*! Length of the generic array to transmit*/
+  long _lgrTabToSend;
+  /*! it represents the sizeof() of each component of the generic array:\n
+    Practically in terms of bytes the size to be transmitted is _lgrTabToSend*_sizeOf
+  */
+  int _sizeOf;
+  /*! Type the component of the array*/
+  SALOME::TypeOfDataTransmitted _type;
+
+  SALOME_Sender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf);
+public:
+  const void *getData(long &size) const;
+  int getSizeOf() const;
+  void release();
+  SALOME::TypeOfDataTransmitted getTypeOfDataTransmitted();
+  SALOME::Sender_ptr buildOtherWithProtocol(SALOME::TypeOfCommunication type);
+  static SALOME_Sender_i *find(SALOME::Sender_ptr pCorba);
+};
+
+/*! Servant class for CORBA sender for double* when no copy of array _tabToSend is required, that is to say double and CORBA::Double are binary equal.
+ */
+class SALOME_CorbaDoubleNCSender_i : public POA_SALOME::CorbaDoubleNCSender,
+                                    public SALOME_Sender_i
+{
+public:
+  SALOME_CorbaDoubleNCSender_i(const double *tabToSend,long lgrTabToSend);
+  ~SALOME_CorbaDoubleNCSender_i();
+  CORBA::ULong getSize();
+  SALOME::vectorOfDouble* sendPart(CORBA::ULong offset, CORBA::ULong length);
+  SALOME::vectorOfDouble* send();
+};
+
+/*! Servant class for CORBA sender for double* when copy of array _tabToSend is required, that is to say double and CORBA::Double are NOT binary equal.
+ */
+class SALOME_CorbaDoubleCSender_i : public POA_SALOME::CorbaDoubleCSender,
+                                   public SALOME_Sender_i
+{
+public:
+  SALOME_CorbaDoubleCSender_i(const double *tabToSend,const long lgrTabToSend);
+  ~SALOME_CorbaDoubleCSender_i();
+  CORBA::ULong getSize();
+  SALOME::vectorOfDouble* sendPart(CORBA::ULong offset, CORBA::ULong length);
+};
+
+/*! Servant class for CORBA sender for int* when no copy of array _tabToSend is required, that is to say int and CORBA::Long are binary equal.
+ */
+class SALOME_CorbaLongNCSender_i : public POA_SALOME::CorbaLongNCSender,
+                                  public SALOME_Sender_i
+{
+public:
+  SALOME_CorbaLongNCSender_i(const int *tabToSend,const long lgrTabToSend);
+  ~SALOME_CorbaLongNCSender_i();
+  CORBA::ULong getSize();
+  SALOME::vectorOfLong* sendPart(CORBA::ULong offset, CORBA::ULong length);
+  SALOME::vectorOfLong* send();
+};
+
+/*! Servant class for CORBA sender for int* when copy of array _tabToSend is required, that is to say int and CORBA::Long are NOT binary equal.
+ */
+class SALOME_CorbaLongCSender_i : public POA_SALOME::CorbaLongCSender,
+                                 public SALOME_Sender_i
+{
+public:
+  SALOME_CorbaLongCSender_i(const int *tabToSend,long lgrTabToSend);
+  ~SALOME_CorbaLongCSender_i();
+  CORBA::ULong getSize();
+  SALOME::vectorOfLong* sendPart(CORBA::ULong offset, CORBA::ULong length);
+  SALOME::CorbaLongCSender_ptr _this();
+};
+
+#ifdef HAVE_MPI2
+
+/*! Servant class of sender using MPI2.
+ */
+class SALOME_MPISender_i : public POA_SALOME::MPISender,
+                          public SALOME_Sender_i
+{
+private:
+  static unsigned long _tag1;
+  static unsigned long _tag2;
+  /*! Name of the port opened*/
+  char *_portName;
+  int _cproc;
+  /*! Tag 1 that identifies the transfert*/
+  int _tag1Inst;
+  /*! Tag 2 that identifies the transfert*/
+  int _tag2Inst;
+  /*! MPI communicator*/
+  MPI_Comm _com;
+  /*! Array of pointer for asynchronous invocation with omnithread*/
+  void **_argsForThr;
+  /*! Pointer to thread created on asynchronous invocation*/
+  omni_thread *_newThr;
+public:
+  SALOME_MPISender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf);
+  ~SALOME_MPISender_i();
+  SALOME::MPISender::param* getParam();
+  void send();
+  void close(const SALOME::MPISender::param& p);
+private:
+  static void* myThread(void *args);
+};
+
+#endif
+
+#ifdef HAVE_SOCKET
+
+/*! Servant class of sender using Sockets.
+ */
+class SALOME_SocketSender_i : public POA_SALOME::SocketSender,
+                             public SALOME_Sender_i
+{
+private:
+  int _serverSockfd;
+  int _clientSockfd;
+  int _port;
+  std::string _IPAddress;
+  void **_argsForThr;
+  omni_thread *_newThr;
+  bool _errorFlag;
+public:
+  SALOME_SocketSender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf);
+  ~SALOME_SocketSender_i();
+  SALOME::SocketSender::param* getParam();
+  void send();
+  void initCom() throw(SALOME::SALOME_Exception);
+  void acceptCom() throw(SALOME::SALOME_Exception);
+  void endOfCom();
+  void closeCom();
+private:
+  static void* myThread(void *args);
+  std::string inetAddress();
+};
+
+#endif
+
+#endif
+
diff --git a/src/Communication/SenderFactory.cxx b/src/Communication/SenderFactory.cxx
new file mode 100644 (file)
index 0000000..35b4af0
--- /dev/null
@@ -0,0 +1,98 @@
+#include "SenderFactory.hxx"
+#include "utilities.h"
+#include "SALOMEMultiComm.hxx"
+#include "SALOME_Comm_i.hxx"
+
+#ifdef COMP_CORBA_DOUBLE
+#define SALOME_CorbaDoubleSender SALOME_CorbaDoubleNCSender_i
+#else
+#define SALOME_CorbaDoubleSender SALOME_CorbaDoubleCSender_i
+#endif
+
+#ifdef COMP_CORBA_LONG
+#define SALOME_CorbaLongSender SALOME_CorbaLongNCSender_i
+#else
+#define SALOME_CorbaLongSender SALOME_CorbaLongCSender_i
+#endif
+
+SALOME::Sender_ptr SenderFactory::buildSender(SALOMEMultiComm &multiCommunicator,const double *tab,long lgr)throw(MultiCommException){
+  switch(multiCommunicator.getProtocol())
+    {
+    case SALOME::CORBA_:
+      {
+       SALOME_CorbaDoubleSender * retc=new SALOME_CorbaDoubleSender(tab,lgr);
+       return retc->_this();
+      }
+#ifdef HAVE_MPI2
+    case SALOME::MPI_:
+      {
+       SALOME_MPISender_i* retm=new SALOME_MPISender_i(SALOME::DOUBLE_,tab,lgr,sizeof(double));
+       return retm->_this();
+      }
+#endif
+#ifdef HAVE_SOCKET
+    case SALOME::SOCKET_:
+      {
+       SALOME_SocketSender_i* rets=new SALOME_SocketSender_i(SALOME::DOUBLE_,tab,lgr,sizeof(double));
+       return rets->_this();
+      }
+#endif
+    default:
+      {
+       multiCommunicator.setProtocol(SALOME::CORBA_);
+       MESSAGE("PROTOCOL CHANGED TO CORBA");
+       SALOME_CorbaDoubleSender * retc=new SALOME_CorbaDoubleSender(tab,lgr);
+       return retc->_this();
+      }
+//       throw MultiCommException("Communication protocol not implemented");
+    }
+}
+
+SALOME::Sender_ptr SenderFactory::buildSender(SALOMEMultiComm &multiCommunicator,const int *tab,long lgr)throw(MultiCommException){
+  switch(multiCommunicator.getProtocol())
+    {
+    case SALOME::CORBA_:
+      {
+       SALOME_CorbaLongSender * retc=new SALOME_CorbaLongSender(tab,lgr);
+       return retc->_this();
+      }
+#ifdef HAVE_MPI2
+    case SALOME::MPI_:
+      {
+       SALOME_MPISender_i* retm=new SALOME_MPISender_i(SALOME::INT_,tab,lgr,sizeof(int));
+       return retm->_this();
+      }
+#endif
+#ifdef HAVE_SOCKET
+    case SALOME::SOCKET_:
+      {
+       SALOME_SocketSender_i* rets=new SALOME_SocketSender_i(SALOME::INT_,tab,lgr,sizeof(int));
+       return rets->_this();
+      }
+#endif
+    default:
+      {
+       multiCommunicator.setProtocol(SALOME::CORBA_);
+       SALOME_CorbaLongSender * retc=new SALOME_CorbaLongSender(tab,lgr);
+       return retc->_this();
+      }
+//       throw MultiCommException("Communication protocol not implemented"); 
+    }
+  }
+
+SALOME::Sender_ptr SenderFactory::buildSender(SALOME::TypeOfCommunication NewType,SALOME_Sender_i *src)
+{
+  SALOMEMultiComm mc(NewType);
+  long n;
+  const void *data=src->getData(n);
+  switch(src->getTypeOfDataTransmitted())
+    {
+    case SALOME::DOUBLE_:
+      return buildSender(mc,(const double *)data,n);
+    case SALOME::INT_:
+      return buildSender(mc,(const int *)data,n);
+    }
+  
+}
+
+
diff --git a/src/Communication/SenderFactory.hxx b/src/Communication/SenderFactory.hxx
new file mode 100644 (file)
index 0000000..d85a842
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _SENDERFACTORY_HXX_
+#define _SENDERFACTORY_HXX_
+
+#include "MultiCommException.hxx"
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOME_Comm)
+
+class SALOMEMultiComm;
+
+class SALOME_Sender_i;
+
+/*!
+  This class implements the factory pattern of GoF by making a sender by giving an array and a communicator.It completely hides the type of sender from the user.
+ */
+class SenderFactory
+{
+public:
+  static SALOME::Sender_ptr buildSender(SALOMEMultiComm &multiCommunicator,const double *tab,long lgr) throw(MultiCommException);
+  static SALOME::Sender_ptr buildSender(SALOMEMultiComm &multiCommunicator,const int *tab,long lgr) throw(MultiCommException);
+  static SALOME::Sender_ptr buildSender(SALOME::TypeOfCommunication NewType,SALOME_Sender_i *src);
+};
+
+#endif
+
index db16def90f7490f683747838a05b6859468a63d0..6d68f0fd7dc48c72a6cbf59b40e0718b71fafe3c 100644 (file)
@@ -51,11 +51,11 @@ BIN = SALOME_Container
 BIN_SRC = SALOME_Container_SignalsHandler.cxx
 BIN_SERVER_IDL = SALOME_Component.idl
 
-CPPFLAGS+= $(PYTHON_INCLUDES) $(OCC_INCLUDES)
+CPPFLAGS+= $(PYTHON_INCLUDES) $(MPI_INCLUDE) $(OCC_INCLUDES)
 CXXFLAGS+=$(OCC_CXXFLAGS)
 
 LDFLAGS+= -lSalomeNS -lRegistry -lOpUtil -lSalomeNotification -lSALOMELocalTrace
 
-LIBS += -Xlinker -export-dynamic $(PYTHON_LIBS) -lCASCatch
+LIBS += -Xlinker -export-dynamic $(PYTHON_LIBS) $(MPI_LIBS) -lCASCatch
 
 @CONCLUDE@
index d8cd500a3994ab7d42aa09b50e1e1c9c962f8290..a324089b700e75ecd93495514c2eebbd8dcce6e5 100644 (file)
 #include <Utils_Timer.hxx>
 #endif
 
+#ifdef HAVE_MPI2
+#include <mpi.h>
+#endif
+
 #include <Python.h>
 
 extern "C" void HandleServerSideSignals(CORBA::ORB_ptr theORB);
@@ -58,6 +62,9 @@ int main(int argc, char* argv[])
   Py_InitModule( "InitPyRunMethod" , MethodPyVoidMethod ) ;
   
   try{
+#ifdef HAVE_MPI2
+      MPI_Init(&argc,&argv);
+#endif
     // Initialise the ORB.
     ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
     ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
@@ -199,6 +206,9 @@ int main(int argc, char* argv[])
   }catch(...){
     INFOS("Caught unknown exception.");
   }
+#ifdef HAVE_MPI2
+  MPI_Finalize();
+#endif
   END_OF(argv[0]);
 }
 
index 22ba51053497cb1bcafe0af1c44a28c0ec562c31..b3fb62e6bb2162abdb544dd2b57781003ee05e92 100644 (file)
@@ -35,7 +35,7 @@ MPIContainer_i::MPIContainer_i(int nbproc, int numproc,
                               CORBA::ORB_ptr orb, 
                               PortableServer::POA_ptr poa,
                               char * containerName) 
-  : Engines_Container_i(orb,poa,containerName,0), MPIObject_i(nbproc,numproc)
+  : Engines_Container_i(orb,poa,containerName,0,0), MPIObject_i(nbproc,numproc)
 {
   _id = _poa->activate_object(this);
 
index 218c01c9db9326679fd7824f88a1b76188ac9236..7f9324a9fdf905dada3b3d08c58ed044957453b0 100644 (file)
@@ -85,14 +85,14 @@ void MPIObject_i::BCastIOR(CORBA::ORB_ptr orb, Engines::MPIObject_var pobj,
 
     // Process 0 recupere les ior de l'object sur les autres process
     for(ip=1;ip<_nbproc;ip++){
-      err = MPI_Recv(&n,1,MPI_INTEGER,ip,ip,MPI_COMM_WORLD,&status);
+      err = MPI_Recv(&n,1,MPI_INT,ip,ip,MPI_COMM_WORLD,&status);
       if(err){
        MESSAGE("[" << _numproc << "] MPI_RECV error");
        exit(1);
       }
       // Allocation de la chaine de longueur n
       ior = (char*)calloc(n,sizeof(char));
-      err = MPI_Recv(ior,n,MPI_CHARACTER,ip,2*ip,MPI_COMM_WORLD,&status);
+      err = MPI_Recv(ior,n,MPI_CHAR,ip,2*ip,MPI_COMM_WORLD,&status);
       if(err){
        MESSAGE("[" << _numproc << "] MPI_RECV error");
        exit(1);
@@ -110,12 +110,12 @@ void MPIObject_i::BCastIOR(CORBA::ORB_ptr orb, Engines::MPIObject_var pobj,
   else{
     // On envoie l'IOR au process 0
     n = strlen((char*)sior);
-    err = MPI_Send(&n,1,MPI_INTEGER,0,_numproc,MPI_COMM_WORLD);
+    err = MPI_Send(&n,1,MPI_INT,0,_numproc,MPI_COMM_WORLD);
     if(err){
       MESSAGE("[" << _numproc << "] MPI_SEND error");
       exit(1);
     }
-    err = MPI_Send((char*)sior,n,MPI_CHARACTER,0,2*_numproc,MPI_COMM_WORLD);
+    err = MPI_Send((char*)sior,n,MPI_CHAR,0,2*_numproc,MPI_COMM_WORLD);
     if(err){
       MESSAGE("[" << _numproc << "] MPI_SEND error");
       exit(1);
index da4e295d95186e4f043a718bddbfcd47a69d1bb4..5576a570a74a10c5631626393929a250a962d51e 100644 (file)
@@ -51,8 +51,8 @@ BIN = SALOME_MPIContainer
 BIN_SRC = 
 BIN_SERVER_IDL = TypeData.idl MPIObject.idl MPIContainer.idl
 
-CXXFLAGS+=${MPICH_INCLUDES}
-CXX_DEPEND_FLAG+=${MPICH_INCLUDES}
-LDFLAGS+= -lSalomeContainer -lSalomeNS -lRegistry -lOpUtil ${MPICH_LIBS} 
+CXXFLAGS+=${MPI_INCLUDES}
+CXX_DEPEND_FLAG+=${MPI_INCLUDES}
+LDFLAGS+= -lSalomeContainer -lSalomeNS -lRegistry -lOpUtil ${MPI_LIBS} 
 
 @CONCLUDE@
index caefd1d0dc21b75a2f817142616aadc24a7e50e3..1eaa66af2d8f26243cd0528f26d1b6f2eab143e8 100644 (file)
@@ -42,14 +42,14 @@ SUBDIRS = MSG2QM SALOMELocalTrace Logger Utils SALOMELogger CASCatch PatchQt \
           SALOMEGUI Plot2d VTKViewer OCCViewer \
          SUPERVGraph \
          Session SALOME_SWIG TOOLSGUI SALOME_PY \
-          RegistryDisplay ModuleGenerator SALOME_PYQT Loader
+          RegistryDisplay ModuleGenerator SALOME_PYQT Loader Communication
 
-ifeq (@WITHOPENPBS@,yes)
-  SUBDIRS += Batch Batch_SWIG
+ifeq (@mpi_ok@,yes)
+  SUBDIRS+= MPIContainer
 endif
 
-ifeq (@WITHMPICH@,yes)
-  SUBDIRS+= MPIContainer
+ifeq (@WITHOPENPBS@,yes)
+  SUBDIRS += Batch Batch_SWIG
 endif
 
 @MODULE@