Salome HOME
ea97dc78845d6bb064ddf49d2fcebab3f0bfd762
[modules/kernel.git] / src / Communication / ReceiverFactory.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #ifdef HAVE_MPI2
24 #include "mpi.h"
25 #endif
26 #include "ReceiverFactory.hxx"
27 #include "Receivers.hxx"
28
29 #ifdef COMP_CORBA_DOUBLE
30 #define CorbaDNoCopyReceiver CorbaNCNoCopyReceiver
31 #define CorbaDWithCopyReceiver CorbaNCWithCopyReceiver
32 #else
33 #define CorbaDNoCopyReceiver CorbaWCNoCopyReceiver
34 #define CorbaDWithCopyReceiver CorbaWCWithCopyReceiver
35 #endif
36
37 #ifdef COMP_CORBA_LONG
38 #define CorbaINoCopyReceiver CorbaNCNoCopyReceiver
39 #define CorbaIWithCopyReceiver CorbaNCWithCopyReceiver
40 #else
41 #define CorbaINoCopyReceiver CorbaWCNoCopyReceiver
42 #define CorbaIWithCopyReceiver CorbaWCWithCopyReceiver
43 #endif
44
45 #ifdef HAVE_SOCKET
46 #include <rpc/xdr.h>
47 #endif
48
49 /*!
50   This method performs the transfert of double array with the remote SenderDouble given. If it fails with this SenderDouble it tries with an another protocol (CORBA by default).
51  */
52 double *ReceiverFactory::getValue(SALOME::SenderDouble_ptr sender,long &size)
53 {
54   double *ret;
55   try{
56     ret=getValueOneShot(sender,size);
57   }
58   catch(MultiCommException&)
59     {
60       SALOME::SenderDouble_ptr newSender=sender->buildOtherWithProtocol(SALOME::CORBA_);
61       MESSAGE("PROTOCOL CHANGED TO CORBA");
62       sender->release();
63       ret=getValueOneShot(newSender,size);
64       CORBA::release(newSender);
65     }
66   return ret;
67 }
68
69 /*!
70   This method performs the transfert of int array with the remote SenderInt given. If it fails with this SenderInt it tries with an another protocol (CORBA by default).
71  */
72 int *ReceiverFactory::getValue(SALOME::SenderInt_ptr sender,long &size)
73 {
74   int *ret;
75   try{
76     ret=getValueOneShot(sender,size);
77   }
78   catch(MultiCommException&)
79     {
80       SALOME::SenderInt_ptr newSender=sender->buildOtherWithProtocol(SALOME::CORBA_);
81       MESSAGE("PROTOCOL CHANGED TO CORBA");
82       sender->release();
83       ret=getValueOneShot(newSender,size);
84       CORBA::release(newSender);
85     }
86   return ret;
87 }
88
89 /*!
90   This method performs the transfert with the remote SenderDouble given. If it fails an exception is thrown.
91  */
92 double *ReceiverFactory::getValueOneShot(SALOME::SenderDouble_ptr sender,long &size)
93 {
94   SALOME::CorbaDoubleNCSender_ptr cncD_ptr;
95   SALOME::CorbaDoubleCSender_ptr cwcD_ptr;
96 #ifdef HAVE_MPI2
97   SALOME::MPISenderDouble_ptr mpi_ptr=SALOME::MPISenderDouble::_narrow(sender);
98 #endif
99 #ifdef HAVE_SOCKET
100   SALOME::SocketSenderDouble_ptr sock_ptr=SALOME::SocketSenderDouble::_narrow(sender);
101 #endif
102   cncD_ptr=SALOME::CorbaDoubleNCSender::_narrow(sender);
103   cwcD_ptr=SALOME::CorbaDoubleCSender::_narrow(sender);
104   if(!CORBA::is_nil(cncD_ptr))
105     {
106       CORBA::release(sender);
107       CorbaDNoCopyReceiver<double,CORBA::Double,SALOME::vectorOfDouble_var,SALOME::CorbaDoubleNCSender_ptr,SALOME::SenderDouble_ptr,SALOME_SenderDouble_i> rec(cncD_ptr);
108       return rec.getValue(size);
109     }
110   else if(!CORBA::is_nil(cwcD_ptr))
111     {
112       CORBA::release(sender);
113       CorbaDWithCopyReceiver<double,CORBA::Double,SALOME::vectorOfDouble_var,SALOME::CorbaDoubleCSender_ptr,SALOME::SenderDouble_ptr,SALOME_SenderDouble_i> rec(cwcD_ptr);
114       return rec.getValue(size);
115     }
116 #ifdef HAVE_MPI2
117   else if(!CORBA::is_nil(mpi_ptr))
118     {
119       CORBA::release(sender);
120       MPIReceiver<double,SALOME::MPISenderDouble_ptr,SALOME::SenderDouble_ptr,SALOME_SenderDouble_i> rec(mpi_ptr);
121       return rec.getValue(size);
122     }
123 #endif
124 #ifdef HAVE_SOCKET
125   else if(!CORBA::is_nil(sock_ptr))
126     {
127       CORBA::release(sender);
128       SocketReceiver<double,xdr_double,SALOME::SocketSenderDouble_ptr,SALOME::SenderDouble_ptr,SALOME_SenderDouble_i> rec(sock_ptr);
129       return rec.getValue(size);
130     }
131 #endif
132   else
133     {
134       throw MultiCommException("Unknown sender protocol");
135       return 0;
136     }
137 }
138
139 /*!
140   This method performs the transfert with the remote SenderInt given. If it fails an exception is thrown.
141  */
142 int *ReceiverFactory::getValueOneShot(SALOME::SenderInt_ptr sender,long &size)
143 {
144   SALOME::CorbaLongNCSender_ptr cncL_ptr;
145   SALOME::CorbaLongCSender_ptr cwcL_ptr;
146 #ifdef HAVE_MPI2
147   SALOME::MPISenderInt_ptr mpi_ptr=SALOME::MPISenderInt::_narrow(sender);
148 #endif
149 #ifdef HAVE_SOCKET
150   SALOME::SocketSenderInt_ptr sock_ptr=SALOME::SocketSenderInt::_narrow(sender);
151 #endif
152   cncL_ptr=SALOME::CorbaLongNCSender::_narrow(sender);
153   cwcL_ptr=SALOME::CorbaLongCSender::_narrow(sender);
154   if(!CORBA::is_nil(cncL_ptr))
155     {
156       CORBA::release(sender);
157       CorbaINoCopyReceiver<int,CORBA::Long,SALOME::vectorOfLong_var,SALOME::CorbaLongNCSender_ptr,SALOME::SenderInt_ptr,SALOME_SenderInt_i> rec(cncL_ptr);
158       return rec.getValue(size);
159     }
160   else if(!CORBA::is_nil(cwcL_ptr))
161     {
162       CORBA::release(sender);
163       CorbaIWithCopyReceiver<int,CORBA::Long,SALOME::vectorOfLong_var,SALOME::CorbaLongCSender_ptr,SALOME::SenderInt_ptr,SALOME_SenderInt_i> rec(cwcL_ptr);
164       return rec.getValue(size);
165     }
166 #ifdef HAVE_MPI2
167   else if(!CORBA::is_nil(mpi_ptr))
168     {
169       CORBA::release(sender);
170       MPIReceiver<int,SALOME::MPISenderInt_ptr,SALOME::SenderInt_ptr,SALOME_SenderInt_i> rec(mpi_ptr);
171       return rec.getValue(size);
172     }
173 #endif
174 #ifdef HAVE_SOCKET
175   else if(!CORBA::is_nil(sock_ptr))
176     {
177       CORBA::release(sender);
178       SocketReceiver<int,xdr_int,SALOME::SocketSenderInt_ptr,SALOME::SenderInt_ptr,SALOME_SenderInt_i> rec(sock_ptr);
179       return rec.getValue(size);
180     }
181 #endif
182   else
183     {
184       throw MultiCommException("Unknown sender protocol");
185       return 0;
186     }
187 }
188
189 SeqByteReceiver::SeqByteReceiver(SALOME::SenderByte_ptr sender):_obj(SALOME::SenderByte::_duplicate(sender))
190 {
191 }
192
193 char *SeqByteReceiver::data(unsigned long& size)
194 {
195   size = _obj->getSize();
196   if(size <= CHUNK_SIZE)
197   {
198     this->fetchOneShot( size );
199     return reinterpret_cast<char *>(_data_one_shot->get_buffer());
200   }
201   else
202   {
203     this->fetchByChunks( size );
204     return _data_for_split_case.get();
205   }
206 }
207
208 void SeqByteReceiver::fetchOneShot(unsigned long size)
209 {
210   _data_one_shot.reset( _obj->sendPart(0,size) );
211 }
212
213 void SeqByteReceiver::fetchByChunks(unsigned long size)
214 {
215   _data_for_split_case.reset( new char[size] );
216   char *destination = _data_for_split_case.get();
217   constexpr unsigned long EFF_CHUNK_SIZE = CHUNK_SIZE / 8;
218   unsigned long iStart = 0;
219   unsigned long iEnd = EFF_CHUNK_SIZE;
220   while( iStart!=iEnd && iEnd <= size )
221   {
222     std::unique_ptr<SALOME::vectorOfByte> part( _obj->sendPart(iStart,iEnd) );
223     const unsigned char *partC = part->get_buffer();
224     std::copy(partC,partC+(iEnd-iStart),destination+iStart);
225     iStart = iEnd; iEnd = std::min(iStart + EFF_CHUNK_SIZE,size);
226   }
227 }
228
229 SeqByteReceiver::~SeqByteReceiver()
230 {
231   _obj->UnRegister();
232 }