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 ---------------------------------------------
CHECK_SWIG
-echo
-echo ---------------------------------------------
-echo testing threads
-echo ---------------------------------------------
-echo
-
-ENABLE_PTHREADS
-
echo
echo ---------------------------------------------
echo testing omniORB
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
IDL_FILES = \
SALOME_Exception.idl \
+ SALOME_Comm.idl \
SALOME_ModuleCatalog.idl \
SALOME_DataTypeCatalog.idl \
SALOME_RessourcesCatalog.idl \
--- /dev/null
+#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();
+ };
+
+};
--- /dev/null
+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
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
--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
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
fi
fi
-AC_LANG_RESTORE
+dnl AC_LANG_RESTORE
AC_MSG_RESULT(for omniORBpy: $omniORBpy_ok)
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
--- /dev/null
+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
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
--- /dev/null
+
+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@
--- /dev/null
+#include "MultiCommException.hxx"
+
+MultiCommException::MultiCommException(const char *message)
+{
+ _message=message;
+}
+
+const char *MultiCommException::what() const
+{
+ return _message.c_str();
+}
--- /dev/null
+#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
+
--- /dev/null
+#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);
+}
+
--- /dev/null
+#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
+
--- /dev/null
+#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;
+ }
+}
+
--- /dev/null
+#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
+
--- /dev/null
+#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
--- /dev/null
+#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
+
--- /dev/null
+#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;
+}
+
+
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
+
--- /dev/null
+#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);
+ }
+
+}
+
+
--- /dev/null
+#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
+
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@
#include <Utils_Timer.hxx>
#endif
+#ifdef HAVE_MPI2
+#include <mpi.h>
+#endif
+
#include <Python.h>
extern "C" void HandleServerSideSignals(CORBA::ORB_ptr theORB);
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()) ;
}catch(...){
INFOS("Caught unknown exception.");
}
+#ifdef HAVE_MPI2
+ MPI_Finalize();
+#endif
END_OF(argv[0]);
}
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);
// 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);
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);
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@
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@