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