1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "SALOME_Comm_i.hxx"
31 #include "omniORB4/poa.h"
32 #include "omnithread.h"
33 #include "Utils_SINGLETON.hxx"
34 #include "Utils_ORB_INIT.hxx"
35 #include "utilities.h"
37 #include "SenderFactory.hxx"
40 CORBA::ORB_var &getGlobalORB(){
41 ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance();
42 CORBA::ORB_var &orb = init(0,0);
47 /*! Return the C++ data associated to the array to transmit.
48 Used when sender and receiver are colocalized.
50 const void *SALOME_Sender_i::getData(long &size) const{
55 /*! Return the sizeof() of each component of the generic array
57 int SALOME_Sender_i::getSizeOf() const {
61 /*! Unique constructor */
62 SALOME_Sender_i::SALOME_Sender_i(const void *tabToSend,long lgrTabToSend,int sizeOf,bool ownTabToSend):_tabToSend(tabToSend),_lgrTabToSend(lgrTabToSend),_sizeOf(sizeOf),_ownTabToSend(ownTabToSend){
65 /*! To force ownerShip status */
66 void SALOME_Sender_i::setOwnerShip(bool own)
71 /*! 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.
73 void SALOME_Sender_i::release()
75 PortableServer::ObjectId_var oid = _default_POA()->servant_to_id(this);
76 _default_POA()->deactivate_object(oid);
80 SALOME_SenderDouble_i::SALOME_SenderDouble_i(const double *tabToSend,long lgrTabToSend,bool ownTabToSend):SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
86 SALOME_SenderDouble_i::~SALOME_SenderDouble_i()
89 delete [] (double *)_tabToSend;
92 /*! Return a new sender of the same array but with an another protocol and delegates to the returned sender the ownership of array.
94 SALOME::SenderDouble_ptr SALOME_SenderDouble_i::buildOtherWithProtocol(SALOME::TypeOfCommunication type)
96 return SenderFactory::buildSender(type,this);
99 /*! Method to establish if the CORBA object referred by pCorba is colocalized.\n
100 If it is, the pointer to the servant that incarnates the CORBA object is returned.
102 SALOME_SenderDouble_i *SALOME_SenderDouble_i::find(SALOME::SenderDouble_ptr pCorba){
103 PortableServer::ServantBase *ret;
105 ret=PortableServer::POA::_the_root_poa()->reference_to_servant(pCorba);
111 return dynamic_cast<SALOME_SenderDouble_i *>(ret);
114 SALOME_SenderInt_i::SALOME_SenderInt_i(const int *tabToSend,long lgrTabToSend,bool ownTabToSend):SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
120 SALOME_SenderInt_i::~SALOME_SenderInt_i()
123 delete [] (int *)_tabToSend;
126 /*! Return a new sender of the same array but with an another protocol.
128 SALOME::SenderInt_ptr SALOME_SenderInt_i::buildOtherWithProtocol(SALOME::TypeOfCommunication type)
130 return SenderFactory::buildSender(type,this);
133 /*! Method to establish if the CORBA object referred by pCorba is colocalized.\n
134 If it is, the pointer to the servant that incarnates the CORBA object is returned.
136 SALOME_SenderInt_i *SALOME_SenderInt_i::find(SALOME::SenderInt_ptr pCorba){
137 PortableServer::ServantBase *ret;
139 ret=PortableServer::POA::_the_root_poa()->reference_to_servant(pCorba);
145 return dynamic_cast<SALOME_SenderInt_i *>(ret);
148 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){
151 SALOME_CorbaDoubleNCSender_i::~SALOME_CorbaDoubleNCSender_i(){
154 CORBA::ULong SALOME_CorbaDoubleNCSender_i::getSize(){
155 CORBA::ULong ret=_lgrTabToSend;
159 SALOME::vectorOfDouble* SALOME_CorbaDoubleNCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
160 SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble(length,length,(CORBA::Double *)((double *)_tabToSend+(long)offset),0);
164 SALOME::vectorOfDouble* SALOME_CorbaDoubleNCSender_i::send(){
165 SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble(_lgrTabToSend,_lgrTabToSend,(CORBA::Double *)_tabToSend,0);
169 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){
172 SALOME_CorbaDoubleCSender_i::~SALOME_CorbaDoubleCSender_i(){
175 CORBA::ULong SALOME_CorbaDoubleCSender_i::getSize(){
176 CORBA::ULong ret=_lgrTabToSend;
180 SALOME::vectorOfDouble* SALOME_CorbaDoubleCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
181 SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble;
183 for (long i=0; i<length; i++)
184 c1[i] = ((double *)_tabToSend)[i+offset];
188 ////////////////////////
190 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){
193 SALOME_CorbaLongNCSender_i::~SALOME_CorbaLongNCSender_i(){
196 CORBA::ULong SALOME_CorbaLongNCSender_i::getSize(){
197 CORBA::ULong ret=_lgrTabToSend;
201 SALOME::vectorOfLong* SALOME_CorbaLongNCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
202 SALOME::vectorOfLong_var c1 = new SALOME::vectorOfLong(length,length,(CORBA::Long *)((long *)_tabToSend+(long)offset),0);
206 SALOME::vectorOfLong* SALOME_CorbaLongNCSender_i::send(){
207 SALOME::vectorOfLong_var c1 = new SALOME::vectorOfLong(_lgrTabToSend,_lgrTabToSend,(CORBA::Long *)_tabToSend,0);
211 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){
214 SALOME_CorbaLongCSender_i::~SALOME_CorbaLongCSender_i(){
217 CORBA::ULong SALOME_CorbaLongCSender_i::getSize(){
218 CORBA::ULong ret=_lgrTabToSend;
222 SALOME::vectorOfLong* SALOME_CorbaLongCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){
223 SALOME::vectorOfLong_var c1 = new SALOME::vectorOfLong;
225 for (long i=0; i<length; i++)
226 c1[i] = ((long *)_tabToSend)[i+offset];
232 unsigned long SALOME_MPISender_i::_tag1=0;
234 unsigned long SALOME_MPISender_i::_tag2=1;
236 SALOME_MPISender_i::SALOME_MPISender_i(const void *tabToSend,long lgrTabToSend,int sizeOf,bool ownTabToSend):SALOME_Sender_i(tabToSend,lgrTabToSend,sizeOf,ownTabToSend){
237 _portName=new char[MPI_MAX_PORT_NAME];
240 SALOME_MPISender_i::~SALOME_MPISender_i(){
244 SALOME::MPISender::param* SALOME_MPISender_i::getParam()
249 SALOME::MPISender::param_var p = new SALOME::MPISender::param;
250 MPI_Comm_rank(MPI_COMM_WORLD,&_cproc);
256 std::string service("toto_");
257 sprintf(stag,"%d_",_tag1);
259 sprintf(stag,"%d_",p->tag2);
261 p->service = CORBA::string_dup(service.c_str());
262 MPI_Open_port(MPI_INFO_NULL, _portName);
263 #if OMPI_MAJOR_VERSION >= 4
264 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
266 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
268 while ( i != TIMEOUT && MPI_Publish_name((char*)service.c_str(),MPI_INFO_NULL,_portName) != MPI_SUCCESS) {
271 #if OMPI_MAJOR_VERSION >= 4
272 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
274 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
276 if ( i == TIMEOUT ) {
277 MPI_Close_port(_portName);
286 void SALOME_MPISender_i::send()
288 _type=getTypeOfDataTransmitted();
289 _argsForThr=new void *[8];
290 _argsForThr[0]=_portName;
291 _argsForThr[1]=&_lgrTabToSend;
292 _argsForThr[2]=(void *)_tabToSend;
293 _argsForThr[3]=&_cproc;
294 _argsForThr[4]=&_tag1Inst;
295 _argsForThr[5]=&_tag2Inst;
296 _argsForThr[6]=&_com;
297 _argsForThr[7]=&_type;
299 _newThr=new omni_thread(SALOME_MPISender_i::myThread,_argsForThr);
303 void* SALOME_MPISender_i::myThread(void *args)
305 void **argsTab=(void **)args;
306 long *lgrTabToSend=(long *)argsTab[1];
307 int *cproc=(int *)argsTab[3];
308 int *tag1=(int *)argsTab[4];
309 int *tag2=(int *)argsTab[5];
310 MPI_Comm *com=(MPI_Comm *)argsTab[6];
311 SALOME::TypeOfDataTransmitted *type=(SALOME::TypeOfDataTransmitted *)argsTab[7];
313 MPI_Comm_accept((char *)argsTab[0],MPI_INFO_NULL,0,MPI_COMM_SELF,com);
314 MPI_Send(lgrTabToSend,1,MPI_LONG,*cproc,*tag1,*com);
317 case SALOME::DOUBLE_:
318 MPI_Send(argsTab[2],*lgrTabToSend,MPI_DOUBLE,*cproc,*tag2,*com);
321 MPI_Send(argsTab[2],*lgrTabToSend,MPI_INT,*cproc,*tag2,*com);
327 void SALOME_MPISender_i::close(const SALOME::MPISender::param& p)
329 std::string service(p.service);
332 MPI_Comm_free(&_com);
333 MPI_Unpublish_name((char *)service.c_str(),MPI_INFO_NULL,_portName);
334 MPI_Close_port(_portName);
335 delete [] _argsForThr;
338 SALOME_MPISenderDouble_i::SALOME_MPISenderDouble_i(const double *tabToSend,long lgrTabToSend,bool ownTabToSend)
339 :SALOME_SenderDouble_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_MPISender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
340 ,SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
344 SALOME_MPISenderInt_i::SALOME_MPISenderInt_i(const int *tabToSend,long lgrTabToSend,bool ownTabToSend)
345 :SALOME_SenderInt_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_MPISender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
346 ,SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
355 #define _POSIX_PII_SOCKET
356 #define _LIBC_POLLUTION_H_
358 #include <sys/types.h>
359 #include <sys/socket.h>
360 #include <netinet/in.h>
361 #include <arpa/inet.h>
365 SALOME_SocketSender_i::SALOME_SocketSender_i(const void *tabToSend,long lgrTabToSend,int sizeOf,bool ownTabToSend):SALOME_Sender_i(tabToSend,lgrTabToSend,sizeOf,ownTabToSend){
366 _IPAddress = inetAddress();
371 SALOME_SocketSender_i::~SALOME_SocketSender_i(){
374 std::string SALOME_SocketSender_i::inetAddress()
377 char t[INET_ADDRSTRLEN+1];
378 struct hostent *host;
379 struct in_addr saddr;
385 saddr.s_addr = inet_addr(s);
386 if (saddr.s_addr != -1)
387 inet_ntop(AF_INET, &saddr, t, INET_ADDRSTRLEN);
389 host = gethostbyname(s);
391 inet_ntop(AF_INET, (struct in_addr *) *host->h_addr_list,
394 return std::string(t);
397 SALOME::SocketSender::param * SALOME_SocketSender_i::getParam()
400 SALOME::SocketSender::param_var p = new SALOME::SocketSender::param;
403 p->lend = _lgrTabToSend - 1;
405 p->internet_address = CORBA::string_dup(_IPAddress.c_str());
410 void SALOME_SocketSender_i::send()
412 _type=getTypeOfDataTransmitted();
413 _argsForThr=new void *[6];
414 _argsForThr[0]=&_serverSockfd;
415 _argsForThr[1]=&_clientSockfd;
416 _argsForThr[2]=&_lgrTabToSend;
417 _argsForThr[3]=(void *)_tabToSend;
418 _argsForThr[4]=&_errorFlag;
419 _argsForThr[5]=&_type;
421 _newThr=new omni_thread(SALOME_SocketSender_i::myThread,_argsForThr);
425 void* SALOME_SocketSender_i::myThread(void *args)
428 void **argsTab=(void **)args;
429 int *serverSockfd=(int *)argsTab[0];
430 int *clientSockfd=(int *)argsTab[1];
431 long *lgrTabToSend=(long *)argsTab[2];
432 void *tabToSend=argsTab[3];
433 bool *errorFlag=(bool*)argsTab[4];
434 SALOME::TypeOfDataTransmitted *type=(SALOME::TypeOfDataTransmitted *)argsTab[5];
436 XDR xp; /* pointeur sur le decodeur XDR */
440 case SALOME::DOUBLE_:
441 xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(double),XDR_ENCODE );
442 xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(double), (xdrproc_t)xdr_double );
445 while( n < *lgrTabToSend*sizeof(double) ){
446 m = write(*clientSockfd, (char*)tabToSend+n, *lgrTabToSend*sizeof(double)-n);
448 if( *clientSockfd >= 0 ){
449 ::close(*clientSockfd);
452 if( *serverSockfd >= 0 ){
453 ::close(*serverSockfd);
462 xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(double),XDR_DECODE );
463 xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(double), (xdrproc_t)xdr_double );
467 xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(int),XDR_ENCODE );
468 xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(int), (xdrproc_t)xdr_int );
471 while( n < *lgrTabToSend*sizeof(int) ){
472 m = write(*clientSockfd, (char*)tabToSend+n, *lgrTabToSend*sizeof(int)-n);
474 if( *clientSockfd >= 0 ){
475 ::close(*clientSockfd);
478 if( *serverSockfd >= 0 ){
479 ::close(*serverSockfd);
488 xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(int),XDR_DECODE );
489 xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(int), (xdrproc_t)xdr_int );
495 void SALOME_SocketSender_i::initCom() throw(SALOME::SALOME_Exception)
497 struct sockaddr_in serv_addr;
499 SALOME::ExceptionStruct es;
501 /* Ouverture de la socket */
502 _serverSockfd = socket(AF_INET , SOCK_STREAM , 0);
503 if(_serverSockfd < 0) {
504 es.type = SALOME::COMM;
505 es.text = "error Socket exception";
506 throw SALOME::SALOME_Exception(es);
508 /* Socket structure initialisation*/
509 bzero((char*)&serv_addr,sizeof(serv_addr));
510 serv_addr.sin_family = AF_INET;
511 serv_addr.sin_port = 0; /* asking for a free port */
512 serv_addr.sin_addr.s_addr = INADDR_ANY;
514 /* Association of socket with a port */
515 if( ::bind(_serverSockfd, (struct sockaddr *) & serv_addr,
516 sizeof(struct sockaddr)) < 0 ) {
518 es.type = SALOME::COMM;
519 es.text = "error bind Socket exception";
520 throw SALOME::SALOME_Exception(es);
522 /* Listening to the allocated port */
523 if( listen(_serverSockfd, 10) < 0 ) {
525 es.type = SALOME::COMM;
526 es.text = "error listen Socket exception";
527 throw SALOME::SALOME_Exception(es);
529 /* Retrieving port number*/
530 if( getsockname(_serverSockfd, (struct sockaddr *) & serv_addr, &n) < 0 ){
532 es.type = SALOME::COMM;
533 es.text = "error getName Socket exception";
534 throw SALOME::SALOME_Exception(es);
536 _port = htons(serv_addr.sin_port);
540 void SALOME_SocketSender_i::acceptCom() throw(SALOME::SALOME_Exception)
543 struct sockaddr_in client_addr;
544 SALOME::ExceptionStruct es;
546 sin_size = sizeof(struct sockaddr_in);
548 _clientSockfd = accept(_serverSockfd, (struct sockaddr *)&client_addr, &sin_size);
549 if( _clientSockfd < 0 ){
551 es.type = SALOME::COMM;
552 es.text = "error accept Socket exception";
553 throw SALOME::SALOME_Exception(es);
557 void SALOME_SocketSender_i::closeCom()
559 if( _clientSockfd >= 0 ){
560 ::close(_clientSockfd);
563 if( _serverSockfd >= 0 ){
564 ::close(_serverSockfd);
570 void SALOME_SocketSender_i::endOfCom()
576 SALOME::ExceptionStruct es;
577 es.type = SALOME::COMM;
578 es.text = "error write Socket exception";
579 throw SALOME::SALOME_Exception(es);
581 delete [] _argsForThr;
584 SALOME_SocketSenderDouble_i::SALOME_SocketSenderDouble_i(const double *tabToSend,long lgrTabToSend,bool ownTabToSend)
585 :SALOME_SenderDouble_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_SocketSender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
586 ,SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(double),ownTabToSend)
590 SALOME_SocketSenderInt_i::SALOME_SocketSenderInt_i(const int *tabToSend,long lgrTabToSend,bool ownTabToSend)
591 :SALOME_SenderInt_i(tabToSend,lgrTabToSend,ownTabToSend),SALOME_SocketSender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
592 ,SALOME_Sender_i(tabToSend,lgrTabToSend,sizeof(int),ownTabToSend)
597 #undef _LIBC_POLLUTION_H_
598 #undef _POSIX_PII_SOCKET