[omniORB] problems with EINTR and errno?

Sai-Lai Lo s.lo@uk.research.att.com
Thu, 24 May 2001 13:50:41 +0100


I suspect either the behaviour of connect() in non-blocking mode has been
changed from glibc 2.1 to glibc 2.2 (which redhat 7.0 is using) or the
kernel you are using is the cause.

The code you are looking at is quite straight forward, it sets the socket to
non-blocking and then do a connect(). On all the systems I've tested, the
expected behaviour is a return value of -1 with errno == EINPROGRESS. The
fact that you are not seeing that indicates a change in behaviour somewhere
on your system.

This could be a bug in glibc or in the kernel you are running. I just don't
know.
There are enough problems with redhat 7.0 that we are staying away from
using it.

Sai-Lai

-----Original Message-----
From: owner-omniorb-list@uk.research.att.com
[mailto:owner-omniorb-list@uk.research.att.com]On Behalf Of Matthew N.
White
Sent: 17 May 2001 16:17
To: omniorb-list@uk.research.att.com
Subject: [omniORB] problems with EINTR and errno?


Hi,
    I'm using omniORB on redhat linux 7.0 (I updated my glibc and
libstdc++).  Basically what I am doing is creating a shared library
which another application loads to access a notification service.  This
application starts a thread that calls ORB_init and attempts to obtain a
reference to an event channel.  I am running into problems when the
application calls

    CORBA::Object_var channel_ref = name_context->resolve(name);

where name is the name of an event channel, and name_context is the
context for the naming service, which was successfully obtained.
A COMM_FAILURE exception is thrown that is resulting from a failed call
to connect() in tcpSocketMTfactory.cc:1271.  The code that is failing
is:

  if (connect(sock,(struct sockaddr *)&raddr,
       sizeof(struct sockaddr_in)) == RC_SOCKET_ERROR)
  {
# ifndef __WIN32__
    if (errno != EINPROGRESS) {
      CLOSESOCKET(sock);
      return RC_INVALID_SOCKET;
    }
    ...

When I run the gdb debugger on the ORB code and break at this point,
looking at errno gives a value of 4, which is EINTR, meaning the call to
connect was interrupted by a signal, which would explain the error.
When I simply printf the value of errno, however, it is zero, which to
to makes no sense to me, but also explains the error.  Modifying to code
to check for an errno of zero, e.g.

 if (connect(sock,(struct sockaddr *)&raddr,
       sizeof(struct sockaddr_in)) == RC_SOCKET_ERROR)
  {
# ifndef __WIN32__
    if (errno != EINPROGRESS && errno != 0) {
      CLOSESOCKET(sock);
      return RC_INVALID_SOCKET;
    }
    ...

causes the application to work fine (it appears), as an experiment.
Also, I don't get these COMM_FAILURE exceptions if I have my application
call ORB_init with its main thread instead of spawning another thread
specifically for this purpose.

So is there anything that could explain this behavior?  Forgive me if
I'm doing something stupid here, I'm very new to CORBA and C++ threads
programming.

Thanks for any replies in advance.

Matt W.