]> SALOME platform Git repositories - modules/kernel.git/blob - src/Communication/SALOME_Comm_i.cxx
Salome HOME
add check on mpi implementation
[modules/kernel.git] / src / Communication / SALOME_Comm_i.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, 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.
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 #include "SALOME_Comm_i.hxx"
24 #ifndef WIN32
25 #include <rpc/xdr.h>
26 #endif
27 #include "omniORB4/poa.h"
28 #include "omnithread.h"
29 #include "Utils_SINGLETON.hxx"
30 #include "Utils_ORB_INIT.hxx"
31 #include "utilities.h"
32
33 #include "SenderFactory.hxx"
34
35 #ifndef WIN32
36 CORBA::ORB_var &getGlobalORB(){
37   ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance();
38   CORBA::ORB_var &orb = init(0,0);
39   return orb;
40 }
41 #endif
42
43 /*! Return the C++ data associated to the array to transmit.
44   Used when sender and receiver are collocalized.
45  */
46 const void *SALOME_Sender_i::getData(long &size) const{
47   size=_lgrTabToSend;
48   return _tabToSend;
49 }
50
51 /*! Return the sizeof() of each component of the generic array
52  */
53 int SALOME_Sender_i::getSizeOf() const {
54   return _sizeOf;
55 }
56
57 /*! Unique constructor */
58 SALOME_Sender_i::SALOME_Sender_i(const void *tabToSend,long lgrTabToSend,int sizeOf,bool ownTabToSend):_tabToSend(tabToSend),_lgrTabToSend(lgrTabToSend),_sizeOf(sizeOf),_ownTabToSend(ownTabToSend){
59 }
60
61 /*! To force ownerShip status */
62 void SALOME_Sender_i::setOwnerShip(bool own)
63 {
64   _ownTabToSend=own;
65 }
66
67 /*! 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.
68  */
69 void SALOME_Sender_i::release()
70 {
71   PortableServer::ObjectId_var oid = _default_POA()->servant_to_id(this);
72   _default_POA()->deactivate_object(oid);
73   _remove_ref();
74 }
75
76 SALOME_SenderDouble_i::SALOME_SenderDouble_i(const double *tabToSend,long lgrTabToSend,bool ownTabToSend):SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
77 {
78 }
79
80 /*! Destructor.
81  */
82 SALOME_SenderDouble_i::~SALOME_SenderDouble_i()
83 {
84   if(_ownTabToSend)
85     delete [] (double *)_tabToSend;
86 }
87
88 /*! Return a new sender of the same array but with an another protocol and delegates to the returned sender the ownership of array.
89  */
90 SALOME::SenderDouble_ptr SALOME_SenderDouble_i::buildOtherWithProtocol(SALOME::TypeOfCommunication type)
91 {
92   return SenderFactory::buildSender(type,this);
93 }
94
95 /*! Method to establish if the CORBA object refered by pCorba is collocalised.\n
96   If it is, the pointer to the servant that incarnates the CORBA object is returned.
97 */
98 SALOME_SenderDouble_i *SALOME_SenderDouble_i::find(SALOME::SenderDouble_ptr pCorba){
99   PortableServer::ServantBase *ret;
100   try {
101     ret=PortableServer::POA::_the_root_poa()->reference_to_servant(pCorba);
102   }
103   catch(...){
104     return 0;
105   }
106   ret->_remove_ref();
107   return dynamic_cast<SALOME_SenderDouble_i *>(ret);
108 }
109
110 SALOME_SenderInt_i::SALOME_SenderInt_i(const int *tabToSend,long lgrTabToSend,bool ownTabToSend):SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
111 {
112 }
113
114 /*! Destructor.
115  */
116 SALOME_SenderInt_i::~SALOME_SenderInt_i()
117 {
118   if(_ownTabToSend)
119     delete [] (int *)_tabToSend;
120 }
121
122 /*! Return a new sender of the same array but with an another protocol.
123  */
124 SALOME::SenderInt_ptr SALOME_SenderInt_i::buildOtherWithProtocol(SALOME::TypeOfCommunication type)
125 {
126   return SenderFactory::buildSender(type,this);
127 }
128
129 /*! Method to establish if the CORBA object refered by pCorba is collocalised.\n
130   If it is, the pointer to the servant that incarnates the CORBA object is returned.
131 */
132 SALOME_SenderInt_i *SALOME_SenderInt_i::find(SALOME::SenderInt_ptr pCorba){
133   PortableServer::ServantBase *ret;
134   try {
135     ret=PortableServer::POA::_the_root_poa()->reference_to_servant(pCorba);
136   }
137   catch(...){
138     return 0;
139   }
140   ret->_remove_ref();
141   return dynamic_cast<SALOME_SenderInt_i *>(ret);
142 }
143
144 SALOME_CorbaDoubleNCSender_i::SALOME_CorbaDoubleNCSender_i(const double *tabToSend,long lgrTabToSend,bool ownTabToSend):SALOME_SenderDouble_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend){
145 }
146
147 SALOME_CorbaDoubleNCSender_i::~SALOME_CorbaDoubleNCSender_i(){
148 }
149
150 CORBA::ULong SALOME_CorbaDoubleNCSender_i::getSize(){
151   CORBA::ULong ret=_lgrTabToSend;
152   return ret;
153 }
154
155 SALOME::vectorOfDouble* SALOME_CorbaDoubleNCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
156   SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble(length,length,(CORBA::Double *)((double *)_tabToSend+(long)offset),0);
157   return c1._retn();
158 }
159
160 SALOME::vectorOfDouble* SALOME_CorbaDoubleNCSender_i::send(){
161   SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble(_lgrTabToSend,_lgrTabToSend,(CORBA::Double *)_tabToSend,0);
162   return c1._retn();
163 }
164
165 SALOME_CorbaDoubleCSender_i::SALOME_CorbaDoubleCSender_i(const double *tabToSend,long lgrTabToSend,bool ownTabToSend):SALOME_SenderDouble_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend){
166 }
167
168 SALOME_CorbaDoubleCSender_i::~SALOME_CorbaDoubleCSender_i(){
169 }
170
171 CORBA::ULong SALOME_CorbaDoubleCSender_i::getSize(){
172   CORBA::ULong ret=_lgrTabToSend;
173   return ret;
174 }
175
176 SALOME::vectorOfDouble* SALOME_CorbaDoubleCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
177   SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble;
178   c1->length(length);
179   for (long i=0; i<length; i++)
180     c1[i] = ((double *)_tabToSend)[i+offset];
181   return c1._retn();
182 }
183
184 ////////////////////////
185
186 SALOME_CorbaLongNCSender_i::SALOME_CorbaLongNCSender_i(const int *tabToSend,long lgrTabToSend,bool ownTabToSend):SALOME_SenderInt_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend){
187 }
188
189 SALOME_CorbaLongNCSender_i::~SALOME_CorbaLongNCSender_i(){
190 }
191
192 CORBA::ULong SALOME_CorbaLongNCSender_i::getSize(){
193   CORBA::ULong ret=_lgrTabToSend;
194   return ret;
195 }
196
197 SALOME::vectorOfLong* SALOME_CorbaLongNCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
198   SALOME::vectorOfLong_var c1 = new SALOME::vectorOfLong(length,length,(CORBA::Long *)((long *)_tabToSend+(long)offset),0);
199   return c1._retn();
200 }
201
202 SALOME::vectorOfLong* SALOME_CorbaLongNCSender_i::send(){
203   SALOME::vectorOfLong_var c1 = new SALOME::vectorOfLong(_lgrTabToSend,_lgrTabToSend,(CORBA::Long *)_tabToSend,0);
204   return c1._retn();
205 }
206
207 SALOME_CorbaLongCSender_i::SALOME_CorbaLongCSender_i(const int *tabToSend,long lgrTabToSend,bool ownTabToSend):SALOME_SenderInt_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend){
208 }
209
210 SALOME_CorbaLongCSender_i::~SALOME_CorbaLongCSender_i(){
211 }
212
213 CORBA::ULong SALOME_CorbaLongCSender_i::getSize(){
214   CORBA::ULong ret=_lgrTabToSend;
215   return ret;
216 }
217
218 SALOME::vectorOfLong* SALOME_CorbaLongCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
219   SALOME::vectorOfLong_var c1 = new SALOME::vectorOfLong;
220   c1->length(length);
221   for (long i=0; i<length; i++)
222     c1[i] = ((long *)_tabToSend)[i+offset];
223   return c1._retn();
224 }
225
226 #ifdef HAVE_MPI2
227
228 unsigned long SALOME_MPISender_i::_tag1=0;
229
230 unsigned long SALOME_MPISender_i::_tag2=1;
231
232 SALOME_MPISender_i::SALOME_MPISender_i(const void *tabToSend,long lgrTabToSend,int sizeOf,bool ownTabToSend):SALOME_Sender_i(tabToSend,lgrTabToSend,sizeOf,ownTabToSend){
233   _portName=new char[MPI_MAX_PORT_NAME];
234 }
235
236 SALOME_MPISender_i::~SALOME_MPISender_i(){
237   delete [] _portName;
238 }
239
240 SALOME::MPISender::param* SALOME_MPISender_i::getParam()
241 {
242   char stag[12];
243   int i=0;
244
245   SALOME::MPISender::param_var p = new SALOME::MPISender::param;
246   MPI_Comm_rank(MPI_COMM_WORLD,&_cproc);
247   p->myproc = _cproc;
248   p->tag1 = _tag1;
249   _tag1Inst=_tag1;
250   p->tag2 =_tag2;
251   _tag2Inst=_tag2;
252   std::string service("toto_");
253   sprintf(stag,"%d_",_tag1);
254   service += stag;
255   sprintf(stag,"%d_",p->tag2);
256   service += stag;
257   p->service = CORBA::string_dup(service.c_str());
258   MPI_Open_port(MPI_INFO_NULL, _portName);
259   MPI_Errhandler_set(MPI_COMM_WORLD,MPI_ERRORS_RETURN);
260   while ( i != TIMEOUT  && MPI_Publish_name((char*)service.c_str(),MPI_INFO_NULL,_portName) != MPI_SUCCESS) {
261     i++;
262   } 
263   MPI_Errhandler_set(MPI_COMM_WORLD,MPI_ERRORS_ARE_FATAL);
264   if ( i == TIMEOUT  ) { 
265     MPI_Close_port(_portName);
266     MPI_Finalize();
267     exit(-1);
268     }
269   _tag1 += 2;
270   _tag2 += 2;
271   return p._retn();
272 }
273
274 void SALOME_MPISender_i::send()
275 {
276   _type=getTypeOfDataTransmitted();
277   _argsForThr=new void *[8];
278   _argsForThr[0]=_portName;
279   _argsForThr[1]=&_lgrTabToSend;
280   _argsForThr[2]=(void *)_tabToSend;
281   _argsForThr[3]=&_cproc;
282   _argsForThr[4]=&_tag1Inst;
283   _argsForThr[5]=&_tag2Inst;
284   _argsForThr[6]=&_com;
285   _argsForThr[7]=&_type;
286
287   _newThr=new omni_thread(SALOME_MPISender_i::myThread,_argsForThr);
288   _newThr->start();
289 }
290
291 void* SALOME_MPISender_i::myThread(void *args)
292 {
293   void **argsTab=(void **)args;
294   long *lgrTabToSend=(long *)argsTab[1];
295   int *cproc=(int *)argsTab[3];
296   int *tag1=(int *)argsTab[4];
297   int *tag2=(int *)argsTab[5];
298   MPI_Comm *com=(MPI_Comm *)argsTab[6];
299   SALOME::TypeOfDataTransmitted *type=(SALOME::TypeOfDataTransmitted *)argsTab[7];
300
301   MPI_Comm_accept((char *)argsTab[0],MPI_INFO_NULL,0,MPI_COMM_SELF,com);
302   MPI_Send(lgrTabToSend,1,MPI_LONG,*cproc,*tag1,*com);
303   switch(*type)
304     { 
305     case SALOME::DOUBLE_:
306       MPI_Send(argsTab[2],*lgrTabToSend,MPI_DOUBLE,*cproc,*tag2,*com);
307       break;
308     case SALOME::INT_:
309       MPI_Send(argsTab[2],*lgrTabToSend,MPI_INT,*cproc,*tag2,*com);
310     }
311   omni_thread::exit();
312   return args;
313 }
314
315 void SALOME_MPISender_i::close(const SALOME::MPISender::param& p)
316 {
317   std::string service(p.service);
318   void *r;
319   _newThr->join(&r);
320   MPI_Comm_free(&_com); 
321   MPI_Unpublish_name((char *)service.c_str(),MPI_INFO_NULL,_portName); 
322   MPI_Close_port(_portName);
323   delete [] _argsForThr;
324 }
325
326 SALOME_MPISenderDouble_i::SALOME_MPISenderDouble_i(const double *tabToSend,long lgrTabToSend,bool ownTabToSend)
327   :SALOME_SenderDouble_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_MPISender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
328   ,SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
329 {
330 }
331
332 SALOME_MPISenderInt_i::SALOME_MPISenderInt_i(const int *tabToSend,long lgrTabToSend,bool ownTabToSend)
333   :SALOME_SenderInt_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_MPISender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
334   ,SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
335 {
336 }
337
338 #endif
339
340 #ifdef HAVE_SOCKET
341
342 //CCRT porting
343 #define _POSIX_PII_SOCKET
344 #define _LIBC_POLLUTION_H_
345
346 #include <sys/types.h>
347 #include <sys/socket.h>
348 #include <netinet/in.h>
349 #include <arpa/inet.h>
350 #include <netdb.h>
351 #include <unistd.h>
352
353 SALOME_SocketSender_i::SALOME_SocketSender_i(const void *tabToSend,long lgrTabToSend,int sizeOf,bool ownTabToSend):SALOME_Sender_i(tabToSend,lgrTabToSend,sizeOf,ownTabToSend){
354   _IPAddress = inetAddress();
355   _serverSockfd = -1;
356   _clientSockfd = -1;
357 }
358
359 SALOME_SocketSender_i::~SALOME_SocketSender_i(){
360 }
361
362 std::string SALOME_SocketSender_i::inetAddress()
363 {
364    char s[256];
365    char t[INET_ADDRSTRLEN+1];
366    struct hostent *host;
367    struct in_addr saddr;
368
369    gethostname(s, 255);
370
371    *t = '\0';
372
373    saddr.s_addr = inet_addr(s);
374    if (saddr.s_addr != -1)
375       inet_ntop(AF_INET, &saddr, t, INET_ADDRSTRLEN);
376    else {
377       host = gethostbyname(s);
378       if (host != NULL)
379          inet_ntop(AF_INET, (struct in_addr *) *host->h_addr_list, 
380                    t, INET_ADDRSTRLEN);
381    }
382    return std::string(t);
383 }
384
385 SALOME::SocketSender::param * SALOME_SocketSender_i::getParam()
386 {
387
388   SALOME::SocketSender::param_var p = new SALOME::SocketSender::param;
389
390   p->lstart = 0;
391   p->lend = _lgrTabToSend - 1;
392   p->myport = _port;
393   p->internet_address = CORBA::string_dup(_IPAddress.c_str());
394
395   return p._retn();
396 }
397
398 void SALOME_SocketSender_i::send()
399 {
400   _type=getTypeOfDataTransmitted();
401   _argsForThr=new void *[6];
402   _argsForThr[0]=&_serverSockfd;
403   _argsForThr[1]=&_clientSockfd;
404   _argsForThr[2]=&_lgrTabToSend;
405   _argsForThr[3]=(void *)_tabToSend;
406   _argsForThr[4]=&_errorFlag;
407   _argsForThr[5]=&_type;
408
409   _newThr=new omni_thread(SALOME_SocketSender_i::myThread,_argsForThr);
410   _newThr->start();
411 }
412
413 void* SALOME_SocketSender_i::myThread(void *args)
414 {
415   int n=0, m;
416   void **argsTab=(void **)args;
417   int *serverSockfd=(int *)argsTab[0];
418   int *clientSockfd=(int *)argsTab[1];
419   long *lgrTabToSend=(long *)argsTab[2];
420   void *tabToSend=argsTab[3];
421   bool *errorFlag=(bool*)argsTab[4];
422   SALOME::TypeOfDataTransmitted *type=(SALOME::TypeOfDataTransmitted *)argsTab[5];
423   
424   XDR xp; /* pointeur sur le decodeur XDR */
425   
426   switch(*type)
427     { 
428     case SALOME::DOUBLE_:
429       xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(double),XDR_ENCODE );
430       xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(double), (xdrproc_t)xdr_double );
431
432       *errorFlag = false;
433       while( n < *lgrTabToSend*sizeof(double) ){
434         m = write(*clientSockfd, (char*)tabToSend+n, *lgrTabToSend*sizeof(double)-n);
435         if( m < 0 ){
436           if( *clientSockfd >= 0 ){
437             ::close(*clientSockfd);
438             *clientSockfd = -1;
439           }
440           if( *serverSockfd >= 0 ){
441             ::close(*serverSockfd);
442             *serverSockfd = -1;
443           }
444           *errorFlag = true;
445         }
446         n += m;
447       }
448       xdr_destroy( &xp );
449
450       xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(double),XDR_DECODE );
451       xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(double), (xdrproc_t)xdr_double );
452       xdr_destroy( &xp );
453       break;
454     case SALOME::INT_:
455       xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(int),XDR_ENCODE );
456       xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(int), (xdrproc_t)xdr_int );
457
458       *errorFlag = false;
459       while( n < *lgrTabToSend*sizeof(int) ){
460         m = write(*clientSockfd, (char*)tabToSend+n, *lgrTabToSend*sizeof(int)-n);
461         if( m < 0 ){
462           if( *clientSockfd >= 0 ){
463             ::close(*clientSockfd);
464             *clientSockfd = -1;
465           }
466           if( *serverSockfd >= 0 ){
467             ::close(*serverSockfd);
468             *serverSockfd = -1;
469           }
470           *errorFlag = true;
471         }
472         n += m;
473       }
474       xdr_destroy( &xp );
475
476       xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(int),XDR_DECODE );
477       xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(int), (xdrproc_t)xdr_int );
478       xdr_destroy( &xp );
479     }
480   return args;
481 }
482
483 void SALOME_SocketSender_i::initCom() throw(SALOME::SALOME_Exception)
484 {
485   struct sockaddr_in serv_addr;
486   socklen_t n;
487   SALOME::ExceptionStruct es;
488
489   /* Ouverture de la socket */
490   _serverSockfd = socket(AF_INET , SOCK_STREAM , 0);
491   if(_serverSockfd < 0) {
492     es.type = SALOME::COMM;
493     es.text = "error Socket exception";
494     throw SALOME::SALOME_Exception(es);
495   }
496   /* Socket structure initialisation*/
497   bzero((char*)&serv_addr,sizeof(serv_addr));
498   serv_addr.sin_family = AF_INET;
499   serv_addr.sin_port = 0; /* asking for a free port */
500   serv_addr.sin_addr.s_addr = INADDR_ANY;
501
502   /* Association of socket with a port */
503   if( ::bind(_serverSockfd, (struct sockaddr *) & serv_addr, 
504            sizeof(struct sockaddr)) < 0 ) {
505     closeCom();
506     es.type = SALOME::COMM;
507     es.text = "error bind Socket exception";
508     throw SALOME::SALOME_Exception(es);
509   }
510   /* Listening to the allocated port */
511   if( listen(_serverSockfd, 10) < 0 ) {
512     closeCom();
513     es.type = SALOME::COMM;
514     es.text = "error listen Socket exception";
515     throw SALOME::SALOME_Exception(es);
516   }
517   /* Retrieving port number*/
518   if( getsockname(_serverSockfd, (struct sockaddr *) & serv_addr, &n) < 0 ){
519     closeCom();
520     es.type = SALOME::COMM;
521     es.text = "error getName Socket exception";
522     throw SALOME::SALOME_Exception(es);
523   }
524   _port = htons(serv_addr.sin_port);
525   SCRUTE(_port);
526 }
527
528 void SALOME_SocketSender_i::acceptCom() throw(SALOME::SALOME_Exception)
529 {
530   socklen_t sin_size;
531   struct sockaddr_in client_addr;
532   SALOME::ExceptionStruct es;
533
534   sin_size = sizeof(struct sockaddr_in);
535   
536   _clientSockfd = accept(_serverSockfd, (struct sockaddr *)&client_addr, &sin_size);
537   if( _clientSockfd < 0 ){
538     closeCom();
539     es.type = SALOME::COMM;
540     es.text = "error accept Socket exception";
541     throw SALOME::SALOME_Exception(es);
542   }
543 }
544
545 void SALOME_SocketSender_i::closeCom()
546 {
547   if( _clientSockfd >= 0 ){
548     ::close(_clientSockfd);
549     _clientSockfd = -1;
550   }
551   if( _serverSockfd >= 0 ){
552     ::close(_serverSockfd);
553     _serverSockfd = -1;
554   }
555
556 }
557
558 void SALOME_SocketSender_i::endOfCom()
559 {
560   void *r;
561   _newThr->join(&r);
562   if(_errorFlag)
563     {
564       SALOME::ExceptionStruct es;
565       es.type = SALOME::COMM;
566       es.text = "error write Socket exception";
567       throw SALOME::SALOME_Exception(es);
568     }
569   delete [] _argsForThr;
570 }
571
572 SALOME_SocketSenderDouble_i::SALOME_SocketSenderDouble_i(const double *tabToSend,long lgrTabToSend,bool ownTabToSend)
573   :SALOME_SenderDouble_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_SocketSender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
574   ,SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
575 {
576 }
577
578 SALOME_SocketSenderInt_i::SALOME_SocketSenderInt_i(const int *tabToSend,long lgrTabToSend,bool ownTabToSend)
579   :SALOME_SenderInt_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_SocketSender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
580   ,SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
581 {
582 }
583
584 //CCRT porting
585 #undef _LIBC_POLLUTION_H_
586 #undef _POSIX_PII_SOCKET
587
588 #endif