Subject: socket/signal problem tracked down - comments?
From: [email-masked] (Tim Newsham)

7 May 1998 06:09:21 -0700
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
To: [email-masked]

Hi,

    I tracked down the latest signal+sockets problem I posted a test
program for a week or two ago.  In review I had a program that dod several
connect()'s in sequence, and when an alarm came in, it did a siglongjmp
to get out of the loop, then it did more signal operations.  The test
program failed in some cases (but not always) after the signlongjmp.
The same behavior can be seen if instead of siglongjmp'ing out of
the signal handler, the program does socket operations directly in
the signal handler.

I traced down the problem to happen when a signal comes in while
a program is inside the winsock "connect" function.  I assume at
some point this connect function enters the NT kernel to access some
device.  What I think is happening is that the signal comes in while
the connect is blocking in the kernel.  Select does its normal stack
twiddling thing to queue the signal.  Then the thread unblocks and
returns to userland, returning to the signal handler instead of
to the winsocket DLL.  I think at this point winsock's is in an
inconsistent state -- further socket write()'s to other sockets
give strange errors.

The solution?  I think certain "out-calls" from cygwin to other
packages will have to be protected from signal delivery.  This means
no signals can be delivered while certain calls are in progress!  Ack!

In general it might be a good idea to adopt a convention of doing
non-blocking async operations followed by a waiting operation when
possible.  For example:

      protect_from_signals();
          start_async_operation();
      unprotect_signals();
      friendly_interruptable_wait();
          if success return value
          if interrupted, EINTR or restart

As for immediate fix for the connect() problem -- what is the preferred
way to block signals while I'm in cygwin winsup code?  Should I do
normal sigset operations to set the mask, or is there a simpler mechanism
such as grabbing a semaphore or setting a flag?

                                   Tim N.

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".