Signals and the such-like

Conrad Scott
Thu Jul 25 14:55:00 GMT 2002

"Christopher Faylor" <> wrote:
On Thu, Jul 25, 2002 at 09:41:53PM +0100, Conrad Scott wrote:
>So, I've got a piece of code in the fhandler_socket::close method
>that only closes the client's secret event once the client has
>received the server's okay signal *or* a (Unix) signal arrives
>*or* the server closes its end of the connection (i.e. the server
>exits w/o ever accepting the connection).
> What is an "ok" signal in this context?  Are you introducing
> between two processes that wasn't there originally?  That sounds
> dangerous.  It sounds like you will have permission problems to
> about.

This is just what the existing UNIX socket code does: the client
and server both create (win32) events and wait on the other's
event.  The events are created with no security (i.e. anyone can
access them) but with randomly generated names: the idea being
that a process only knows the name if it can open the UNIX domain
socket file that contains the secret number.  I've not changed the
basic idea, just the exact handshaking between the two processes
to avoid the current race condition.

> >*) If the client receives an unhandled signal, e.g. SIGINT, the
> >do_exit function is called, which then calls close_all_files.
> >it does this w/o setting the 'signal_arrived' event, so none of
> >the events are set that the fhandler_socket::close method is
> >waiting on (at least, not in the particular circumstances
> >mentioned here).
> Actually, this is by design.  The process is exiting.  It's
trying to
> exit quickly and not wake up any sleeping threads.  This
reduces, but
> does not eliminate, potential races or deadlocks.
> If you set signal_arrived, you're going to have two threads
operating at
> the same time with unpredictable results.

Currently the main thread doesn't wake up: the signal thread at
this point is running at a higher priority and since it doesn't
suspend (hopefully) the main thread will never get a chance.

The idea was that setting the 'signal_arrived' event would help
prevent the signal thread from suspending and thus make it more
likely that the main thread would never run.  That's not quite
right of course, since the main thread may well be suspended on
the event and thus not runnable except for that.

> We try hard to avoid situations where we rely on cygwin
> behaving predictably on exit.  In your scenario, it sounds like
> would have a hang situation if a process is terminated from the
> manager.

No, the opposite: I'm trying to get the client to die or, at
least, if it blocks in closing the socket (which seems to be
permissible according to SUSv3), then it should still be
interruptible at that point (even if the close is the automatic
close-on-exit? -- not sure).

If the client dies "too soon" i.e. without completing the
handshake with the server, the worst that happens is that the
client's message is discarded by the server as "unauthorised" --
but if there's a signal flying around at the time, this is a
possible outcome in any case.  So no hang situation: except the
one I've got now where the close blocks and signals are ignored so
I can't get the client to die.

In some ways, the "correct" implementation might be to not ignore
signals in do_exit but to allow close routines to block if
necessary and be interruptible if the user gets bored.

Otherwise, a global flag saying "process is exiting" would solve
the problem.

I hope that I'm being clear enough here: I think I'm juggling too
many options in one message to be crystal clear.

// Conrad

More information about the Cygwin-developers mailing list