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