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