[omniORB] OpenVMS patch for omniORB 2.8.0

Bruce Visscher visschb@rjrt.com
Wed, 02 Feb 2000 18:55:24 -0500


This is a multi-part message in MIME format.
--------------FE32EA54F0B9BD2F36FD2CA1
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello omniORBers,

Guenter Kemmerling discovered a problem with the OpenVMS port of omniORB
when transferring large (> 64Kbytes) sequences of built-in types.  It
turns out that sequences of structs is not a problem because in that
case an intermediate buffer is used for alignment which is limited to
8K+8 (IIRC) bytes (thanks to Sai-Lai for the explaination).

Also, I have enhanced the way that exceptions are handled on the VMS
platform.  The problem that this solves is that sometimes it is
necessary to have know the VMS status code in addition to errno
(CORBA::SystemException::minor()).  In C and C++ this is usually handled
by setting errno to EVMSERR and then setting the VMS specific
"variable", vaxc$errno, to the vms status code.  The way I handle this
is by deriving a class in the omniVms_Exceptions namespace from the
CORBA::Exception and adding a micro() member.  Note that this will only
be done in a few cases, so the VMS programmer may still need a standard
CORBA catch handler below the VMS specific one.

I have modified tcpSocketMTfactory.cc to throw
omniVMS_Exception::COMM_FAILURE (dervied from CORBA::COMM_FAILURE) when
the platform is VMS.

In addition, I modified the way in which floating point conversion
errors are handled on the VMS platform.  When an error occurs, an
omniVMS_Exception::MARSHAL (derived from CORBA::MARSHAL) exception is
thrown.  This replaces a call to assert (which was a little rude on my
part;-)).

Finally, I added some diagnostics code in tcpSocketMTfactory.cc that
displays the calling location when an exception is thrown.  I feel a
little guilty for not using the framework that David Riddoch developed
but I was working with 2.8, not 3.0.

Attached, please find a patch that contains these modifications.  These
apply to the omniORB_20000126 CVS snapshot of omniORB 2.8.0.  Tested
only on VMS.

Thanks,

Bruce Visscher
--------------FE32EA54F0B9BD2F36FD2CA1
Content-Type: text/plain; charset=us-ascii;
 name="vms.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="vms.patch"

*** include/omniORB2/VmsExceptions.h	Wed Dec 31 19:00:00 1969
--- newinclude/omniORB2/VmsExceptions.h	Wed Feb 02 16:13:42 2000
***************
*** 0 ****
--- 1,37 ----
+ #ifndef omniORB2_VmsExceptions_h
+ #define omniORB2_VmsExceptions_h
+ 
+ #include <omniORB2/CORBA.h>
+ 
+ _CORBA_MODULE omniVMS_Exceptions
+ 
+ _CORBA_MODULE_BEG
+ 
+   //  Adds vaxc$errno status code (accessable as e.micro()).
+   class COMM_FAILURE : public CORBA::COMM_FAILURE {
+   public:
+     COMM_FAILURE(
+       CORBA::ULong minor, CORBA::CompletionStatus completed, CORBA::ULong micro)
+     throw()
+     : CORBA::COMM_FAILURE(minor, completed), pd_micro(micro) {
+     }
+     CORBA::ULong micro() const throw() {return pd_micro;}
+   private:
+     CORBA::ULong pd_micro;
+   };
+ 
+   class MARSHAL : public CORBA::MARSHAL {
+   public:
+     MARSHAL(
+       CORBA::ULong minor, CORBA::CompletionStatus completed, CORBA::ULong micro)
+     throw()
+     : CORBA::MARSHAL(minor, completed), pd_micro(micro) {
+     }
+     CORBA::ULong micro() const throw() {return pd_micro;}
+   private:
+     CORBA::ULong pd_micro;
+   };
+ 
+ _CORBA_MODULE_END
+ 
+ #endif
*** src/lib/omniORB2/orbcore/corbaDfloat.cc	Wed Sep 22 17:11:38 1999
--- newsrc/lib/omniORB2/orbcore/corbaDfloat.cc	Wed Feb 02 16:15:26 2000
***************
*** 46,51 ****
--- 46,52 ----
  */
  
  #include <omniORB2/CORBA.h>
+ #include <omniORB2/VmsExceptions.h>
  
  #ifdef HAS_pch
  #pragma hdrstop
***************
*** 72,78 ****
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   assert(status &1);
  }
  
  float _CORBA_Float::cvt_d_() const {
--- 73,80 ----
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   if (!(status & 1))
!     throw omniVMS_Exceptions::MARSHAL(EVMSERR, CORBA::COMPLETED_NO, status);
  }
  
  float _CORBA_Float::cvt_d_() const {
***************
*** 86,92 ****
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   assert(status & 1);
    return f;
  }
  
--- 88,95 ----
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   if (!(status & 1))
!     throw omniVMS_Exceptions::MARSHAL(EVMSERR, CORBA::COMPLETED_NO, status);
    return f;
  }
  
***************
*** 100,106 ****
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   assert(status &1);
  }
  
  double _CORBA_Double::cvt_d_() const {
--- 103,110 ----
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   if (!(status & 1))
!     throw omniVMS_Exceptions::MARSHAL(EVMSERR, CORBA::COMPLETED_NO, status);
  }
  
  double _CORBA_Double::cvt_d_() const {
***************
*** 114,120 ****
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   assert(status & 1);
    return d;
  }
  
--- 118,125 ----
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   if (!(status & 1))
!     throw omniVMS_Exceptions::MARSHAL(EVMSERR, CORBA::COMPLETED_NO, status);
    return d;
  }
  
*** src/lib/omniORB2/orbcore/corbaGfloat.cc	Wed Sep 22 17:12:08 1999
--- newsrc/lib/omniORB2/orbcore/corbaGfloat.cc	Wed Feb 02 16:15:38 2000
***************
*** 46,51 ****
--- 46,52 ----
  */
  
  #include <omniORB2/CORBA.h>
+ #include <omniORB2/VmsExceptions.h>
  
  #ifdef HAS_pch
  #pragma hdrstop
***************
*** 72,78 ****
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   assert(status &1);
  }
  
  float _CORBA_Float::cvt_g_() const {
--- 73,80 ----
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   if (!(status & 1))
!     throw omniVMS_Exceptions::MARSHAL(EVMSERR, CORBA::COMPLETED_NO, status);
  }
  
  float _CORBA_Float::cvt_g_() const {
***************
*** 86,92 ****
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   assert(status & 1);
    return f;
  }
  
--- 88,95 ----
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   if (!(status & 1))
!     throw omniVMS_Exceptions::MARSHAL(EVMSERR, CORBA::COMPLETED_NO, status);
    return f;
  }
  
***************
*** 100,106 ****
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   assert(status &1);
  }
  
  double _CORBA_Double::cvt_g_() const {
--- 103,110 ----
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   if (!(status & 1))
!     throw omniVMS_Exceptions::MARSHAL(EVMSERR, CORBA::COMPLETED_NO, status);
  }
  
  double _CORBA_Double::cvt_g_() const {
***************
*** 114,120 ****
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   assert(status & 1);
    return d;
  }
  
--- 118,125 ----
        CVT$M_ROUND_TO_NEAREST
      )
    );
!   if (!(status & 1))
!     throw omniVMS_Exceptions::MARSHAL(EVMSERR, CORBA::COMPLETED_NO, status);
    return d;
  }
  
*** src/lib/omniORB2/orbcore/tcpSocketMTfactory.cc	Mon Dec 06 09:13:58 1999
--- newsrc/lib/omniORB2/orbcore/tcpSocketMTfactory.cc	Wed Feb 02 16:16:14 2000
***************
*** 138,148 ****
    */
  
  #include <omniORB2/CORBA.h>
- 
  #ifdef HAS_pch
  #pragma hdrstop
  #endif
  
  #include <ropeFactory.h>
  #include <tcpSocket.h>
  
--- 138,246 ----
    */
  
  #include <omniORB2/CORBA.h>
  #ifdef HAS_pch
  #pragma hdrstop
  #endif
  
+ #ifdef __VMS
+ #include <omniORB2/VmsExceptions.h>
+ #endif
+ 
+ //  Compile with -DdoTraceExceptions to enable tracing of exceptions.
+ 
+ #ifdef doTraceExceptions
+ 
+ # include <stdio.h>	// for perror
+ 
+ # ifdef HAS_Cplusplus_Namespace
+ 
+ #   define localFunctionStart namespace {
+ #   define localFunctionEnd }
+ 
+ # else
+ 
+ #   define localFunctionStart static inline
+ #   define localFunctionEnd
+ 
+ # endif
+ 
+ localFunctionStart
+   char const* completionName(CORBA::CompletionStatus completion) {
+     switch(completion) {
+       case CORBA::COMPLETED_YES: return "yes";
+       case CORBA::COMPLETED_NO: return "no";
+     }
+     return "maybe";
+   }
+ localFunctionEnd
+ 
+ # define setFunctionName(x) static char const* here=x
+ 
+ # if !defined(__VMS) && !defined(__WIN32__)
+ 
+ localFunctionStart
+   void throwCommFailure(char const* where, CORBA::CompletionStatus c) {
+     int e=errno;
+     perror(where);
+     omniORB::logger log(where);
+     log << "COMM_FAILURE errno " << e << "Completed: " << completionName(c)
+ 	<< '\n';
+     throw CORBA::COMM_FAILURE(e,c);
+   }
+ localFunctionEnd
+ 
+ # elif defined(__WIN32__)
+ 
+ localFunctionStart
+   void throwCommFailure(char const* where, CORBA::CompletionStatus c) {
+     //	XXX - if we're supposed to use WSAGetLastError instead of errno should
+     //	we set errno before calling perror like this?
+     int e=errno=::WSAGetLastError();
+     perror(where);
+     omniORB::logger log(where);
+     log << "COMM_FAILURE errno " << e << " Completed: " << completionName(c)
+ 	<< '\n';
+     throw CORBA::COMM_FAILURE(e,c);
+   }
+ localFunctionEnd
+ 
+ # else // defined(__VMS)
+ 
+ localFunctionStart
+   void throwCommFailure(char const* where, CORBA::CompletionStatus c) {
+     int e=errno;
+     int v=vaxc$errno;
+     perror(where);
+     omniORB::logger log(where);
+     log << "COMM_FAILURE errno " << e << " Completed: " << completionName(c)
+          << " vaxc$errno: " << v << '\n';
+     throw omniVMS_Exceptions::COMM_FAILURE(e,c,v);
+   }
+ localFunctionEnd
+ 
+ # endif	//  defined(__VMS)
+ 
+ #else	// !defined(doTraceExceptions)
+ 
+ # define setFunctionName(x)
+ 
+ # if !defined(__VMS) && !defined(__WIN32__)
+ 
+ #   define throwCommFailure(w,c) throw CORBA::COMM_FAILURE(errno,c)
+ 
+ # elif defined(__WIN32__)
+ 
+ #   define throwCommFailure(w,c) throw CORBA::COMM_FAILURE(::WSAGetLastError(),c)
+ 
+ # else
+ 
+ #   define throwCommFailure(w,c) \
+   throw omniVMS_Exceptions::COMM_FAILURE(errno,c,vaxc$errno)
+ 
+ # endif
+ 
+ #endif	//  !defined(doTraceExceptions)
+ 
  #include <ropeFactory.h>
  #include <tcpSocket.h>
  
***************
*** 468,473 ****
--- 566,572 ----
    : Rope(f->anchor(),maxStrands,1), pd_export(exportflag), 
      pd_shutdown(NO_THREAD), rendezvouser(0)
  {
+   setFunctionName("tcpSocketIncomingRope");
    struct sockaddr_in myaddr;
  
    // For the moment, we do not impose a restriction on the maximum
***************
*** 475,485 ****
    // ignored.
  
    if ((pd_rendezvous = socket(INETSOCKET,SOCK_STREAM,0)) == RC_INVALID_SOCKET) {
! #ifndef __WIN32__
!     throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
!     throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
    }
    myaddr.sin_family = INETSOCKET;
    myaddr.sin_addr.s_addr = INADDR_ANY;
--- 574,580 ----
    // ignored.
  
    if ((pd_rendezvous = socket(INETSOCKET,SOCK_STREAM,0)) == RC_INVALID_SOCKET) {
!     throwCommFailure(here, CORBA::COMPLETED_NO);
    }
    myaddr.sin_family = INETSOCKET;
    myaddr.sin_addr.s_addr = INADDR_ANY;
***************
*** 491,501 ****
  		   SO_REUSEADDR,(char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR)
        {
  	CLOSESOCKET(pd_rendezvous);
! #ifndef __WIN32__
! 	throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
! 	throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
        }
    }
  
--- 586,592 ----
  		   SO_REUSEADDR,(char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR)
        {
  	CLOSESOCKET(pd_rendezvous);
! 	throwCommFailure(here,CORBA::COMPLETED_NO);
        }
    }
  
***************
*** 503,523 ****
  	   sizeof(struct sockaddr_in)) == RC_SOCKET_ERROR) 
    {
      CLOSESOCKET(pd_rendezvous);
! #ifndef __WIN32__
!     throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
!     throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
    }
  
    // Make it a passive socket
    if (listen(pd_rendezvous,5) == RC_SOCKET_ERROR) {
      CLOSESOCKET(pd_rendezvous);
! #ifndef __WIN32__
!     throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
!     throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
    }
    
    {
--- 594,606 ----
  	   sizeof(struct sockaddr_in)) == RC_SOCKET_ERROR) 
    {
      CLOSESOCKET(pd_rendezvous);
!     throwCommFailure(here, CORBA::COMPLETED_NO);
    }
  
    // Make it a passive socket
    if (listen(pd_rendezvous,5) == RC_SOCKET_ERROR) {
      CLOSESOCKET(pd_rendezvous);
!     throwCommFailure(here, CORBA::COMPLETED_NO);
    }
    
    {
***************
*** 537,547 ****
      if (getsockname(pd_rendezvous,
  		    (struct sockaddr *)&myaddr,&l) == RC_SOCKET_ERROR) {
        CLOSESOCKET(pd_rendezvous);
! #ifndef __WIN32__
!       throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
!       throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
      }
  
      e->port(ntohs(myaddr.sin_port));
--- 620,626 ----
      if (getsockname(pd_rendezvous,
  		    (struct sockaddr *)&myaddr,&l) == RC_SOCKET_ERROR) {
        CLOSESOCKET(pd_rendezvous);
!       throwCommFailure(here, CORBA::COMPLETED_NO);
      }
  
      e->port(ntohs(myaddr.sin_port));
***************
*** 860,876 ****
  size_t
  tcpSocketStrand::ll_recv(void* buf, size_t sz)
  {
    if (pd_delay_connect) {
      // We have not connect to the remote host yet. Do the connect now.
      // Note: May block on connect for sometime if the remote host is down
      //
      if ((pd_socket = realConnect(pd_delay_connect)) == RC_INVALID_SOCKET) {
        _setStrandIsDying();
! #ifndef __WIN32__
!       throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
!       throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
      }
      delete pd_delay_connect;
      pd_delay_connect = 0;
--- 939,952 ----
  size_t
  tcpSocketStrand::ll_recv(void* buf, size_t sz)
  {
+   setFunctionName("ll_recv");
    if (pd_delay_connect) {
      // We have not connect to the remote host yet. Do the connect now.
      // Note: May block on connect for sometime if the remote host is down
      //
      if ((pd_socket = realConnect(pd_delay_connect)) == RC_INVALID_SOCKET) {
        _setStrandIsDying();
!       throwCommFailure(here, CORBA::COMPLETED_NO);
      }
      delete pd_delay_connect;
      pd_delay_connect = 0;
***************
*** 878,904 ****
  
    int rx;
    while (1) {
      if ((rx = ::recv(pd_socket,(char*)buf,sz,0)) == RC_SOCKET_ERROR) {
        if (errno == EINTR)
  	continue;
        else
  	{
  	  _setStrandIsDying();
! #ifndef __WIN32__
! 	  throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
! 	  throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
  	}
      }
      else
        if (rx == 0) {
  	_setStrandIsDying();
! #ifndef __WIN32__
! 	throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
! 	throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
        }
      break;
    }
--- 954,979 ----
  
    int rx;
    while (1) {
+ #ifdef __VMS
+     size_t rqSize=sz;
+     if (rqSize > 65535)
+       rqSize=65535;
+     if ((rx = ::recv(pd_socket,(char*)buf,rqSize,0)) == RC_SOCKET_ERROR) {
+ #else
      if ((rx = ::recv(pd_socket,(char*)buf,sz,0)) == RC_SOCKET_ERROR) {
+ #endif
        if (errno == EINTR)
  	continue;
        else
  	{
  	  _setStrandIsDying();
! 	  throwCommFailure(here, CORBA::COMPLETED_NO);
  	}
      }
      else
        if (rx == 0) {
  	_setStrandIsDying();
! 	throwCommFailure(here, CORBA::COMPLETED_NO);
        }
      break;
    }
***************
*** 912,928 ****
  void
  tcpSocketStrand::ll_send(void* buf,size_t sz) 
  {
    if (pd_delay_connect) {
      // We have not connect to the remote host yet. Do the connect now.
      // Note: May block on connect for sometime if the remote host is down
      //
      if ((pd_socket = realConnect(pd_delay_connect)) == RC_INVALID_SOCKET) {
        _setStrandIsDying();
! #ifndef __WIN32__
!       throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
!       throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
      }
      delete pd_delay_connect;
      pd_delay_connect = 0;
--- 987,1000 ----
  void
  tcpSocketStrand::ll_send(void* buf,size_t sz) 
  {
+   setFunctionName("ll_send");
    if (pd_delay_connect) {
      // We have not connect to the remote host yet. Do the connect now.
      // Note: May block on connect for sometime if the remote host is down
      //
      if ((pd_socket = realConnect(pd_delay_connect)) == RC_INVALID_SOCKET) {
        _setStrandIsDying();
!       throwCommFailure(here, CORBA::COMPLETED_NO);
      }
      delete pd_delay_connect;
      pd_delay_connect = 0;
***************
*** 937,967 ****
    }
  
    while (sz) {
      if ((tx = ::send(pd_socket,p,sz,0)) == RC_SOCKET_ERROR) {
  #ifndef __WIN32__
        if (errno == EINTR)
  	continue;
        else {
  	_setStrandIsDying();
! 	throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
        }
  #else
        if (::WSAGetLastError() == WSAEINTR)
   	continue;
        else {
   	_setStrandIsDying();
! 	throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_MAYBE);
        }
  #endif
      }
      else
        if (tx == 0) {
  	_setStrandIsDying();
! #ifndef __WIN32__
! 	throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
! 	throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
        }
      sz -= tx;
      p += tx;
--- 1009,1043 ----
    }
  
    while (sz) {
+ #ifdef __VMS
+     size_t rqSize=sz;
+     if (rqSize > 65535)
+       rqSize=65535;
+     if ((tx = ::send(pd_socket,p,rqSize,0)) == RC_SOCKET_ERROR) {
+ #else
      if ((tx = ::send(pd_socket,p,sz,0)) == RC_SOCKET_ERROR) {
+ #endif
+ 
  #ifndef __WIN32__
        if (errno == EINTR)
  	continue;
        else {
  	_setStrandIsDying();
! 	throwCommFailure(here, CORBA::COMPLETED_NO);
        }
  #else
        if (::WSAGetLastError() == WSAEINTR)
   	continue;
        else {
   	_setStrandIsDying();
! 	throwCommFailure(here, CORBA::COMPLETED_MAYBE);
        }
  #endif
      }
      else
        if (tx == 0) {
  	_setStrandIsDying();
! 	throwCommFailure(here, CORBA::COMPLETED_NO);
        }
      sz -= tx;
      p += tx;
***************
*** 1134,1139 ****
--- 1210,1216 ----
  void*
  tcpSocketRendezvouser::run_undetached(void *arg)
  {
+   setFunctionName("run_undetached");
    tcpSocketIncomingRope* r = (tcpSocketIncomingRope*) arg;
  
  #if defined(__sunos__) && defined(__sparc__) && __OSVERSION__ >= 5
***************
*** 1169,1180 ****
        PTRACE("Rendezvouser","block on accept()");
  
        if ((new_sock = ::accept(r->pd_rendezvous,(struct sockaddr *)&raddr,&l)) 
! 	                          == RC_INVALID_SOCKET) {
! #ifndef __WIN32__
! 	throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
! #else
! 	throw CORBA::COMM_FAILURE(::WSAGetLastError(),CORBA::COMPLETED_NO);
! #endif
        }
  
        PTRACE("Rendezvouser","unblock from accept()");
--- 1246,1253 ----
        PTRACE("Rendezvouser","block on accept()");
  
        if ((new_sock = ::accept(r->pd_rendezvous,(struct sockaddr *)&raddr,&l)) 
! 				  == RC_INVALID_SOCKET) {
! 	throwCommFailure(here, CORBA::COMPLETED_NO);
        }
  
        PTRACE("Rendezvouser","unblock from accept()");

--------------FE32EA54F0B9BD2F36FD2CA1--