delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/1998/05/07/06:09:21

From: newsham AT lava DOT net (Tim Newsham)
Subject: socket/signal problem tracked down - comments?
7 May 1998 06:09:21 -0700 :
Message-ID: <m0yXJ0K-0011BMC.cygnus.gnu-win32@malasada.lava.net>
Mime-Version: 1.0
To: gnu-win32 AT cygnus DOT com

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
"gnu-win32-request AT cygnus DOT com" with one line of text: "help".

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019