Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/how-signals-work.txt')
-rw-r--r--winsup/cygwin/how-signals-work.txt132
1 files changed, 0 insertions, 132 deletions
diff --git a/winsup/cygwin/how-signals-work.txt b/winsup/cygwin/how-signals-work.txt
deleted file mode 100644
index 3b36badc8..000000000
--- a/winsup/cygwin/how-signals-work.txt
+++ /dev/null
@@ -1,132 +0,0 @@
-Copyright 2001 Red Hat Inc., Christopher Faylor
-
-How do signals work?
-
-On process startup, cygwin starts a secondary thread that deals with signals.
-This thread contains a loop which blocks waiting for one of three events:
-
-1) sigcatch_main - a semaphore which, when incremented, indicates that a
- signal may be available for the main thread. The caller waits for the
- signal to be delivered before returning.
-
-2) sigcatch_nonmain - a semaphore which , when incremented, indicates that
- a signal is available for a non-main thread (currently this is not truly
- implemented). The caller waits for the signal to be delivered before
- returning.
-
-3) sigcatch_nosync - a semaphore which, when incremented, indicates that
- a signal may be available for the main thread. The caller does not wait
- for the delivery of the signal before returning.
-
-So, the signal handler blocks waiting for one of these three semaphores.
-
-If one of these is activated, then the the signal handler inspects an
-array of integers looking for a non-zero value. The array corresponds
-to the normal UNIX signals + two extra locations for internal usage.
-This array is located in the 'sigtodo' array in the procinfo class.
-
-The signal thread uses the InterlockedDecrement function to atomically
-inspect elements of the array. If one one of the elements of the array
-is non-zero, then cygwin checks to see if the user has blocked the
-signal by inspecting the process signal mask. If the signal is blocked,
-then the current array element is reincremented and the next element is
-checked.
-
-If the signal is not blocked, then the function "sig_handle" is called
-with the signal number as an argument. This is a fairly straightforward
-function. It first checks to see if the signal is special in any way.
-
-A special signal is something like SIGKILL or SIGSTOP. The user has no
-control over how those signals affect a UNIX process. If a SIGKILL is
-received then sig_handle calls exit_sig to exit the process. If SIGSTOP
-is called then sig_handle calls the regular signal dispatch function
-with a special function argument "sig_handle_tty_stop". The signal
-dispatch function is described below.
-
-An uncaught signal like SIGTERM or SIGHUP will cause the process to exit
-with the standard UNIX exit values. Uncaught signals like SIGUSR1 are
-ignored, as on UNIX.
-
-If the signal has an associated signal handler, then the setup_handler
-function is eventually called. It is passed the signal, the address of
-the handler, and a standard UNIX sigaction structure. The meat of
-signal processing is in setup_handler.
-
-setup_handler has a "simple" task. It tries to stop the appropriate
-thread and redirect its execution to the signal handler function.
-Currently, the "appropriate thread" is only the main thread. Someday
-we'll have to change this to allow cygwin to interrupt other user
-threads.
-
-To accomplish its task, setup_handler first inspects the static sigsave
-structure. This structure contains information on any not-yet-handled
-signals that may have been set up by a previous call to setup_handler
-but not yet dispatched in the main thread. If the sigsave structure
-seems to be "active", then a "pending" flag is set (see below) and the
-function returns. Otherwise processing continues.
-
-After determining that sigsave is available, setup_handler will take one
-of two routes, depending on whether the main thread is executing in the
-cygwin DLL or is currently in "user" code. We'll discuss the cygwin DLL
-case first.
-
-If sigsave seems to be available, then the frame information for the
-main thread is inspected. This information is set by any cygwin
-function that is known to block (such as _read()), usually by calling
-'sigframe thisframe (mainthread)' in the cygwin function. This call
-sets up information about the current stack frame of an executing cygwin
-process. Any function which uses 'sigframe thisframe' should be signal
-aware. It should detect when a signal has arrived and return
-immediately. This method is also used throughout the DLL to ensure
-accurate frame info for the executing function. So, you'll see it
-sprinkled liberally throughout the DLL, usually at places where
-empirical tests have indicated problems finding this address via the
-brute force method stack walking method employed in setup_handler.
-
-So, if mainframe is active, that means that we have good information
-about the state of the main thread. Cygwin uses the stack frame info
-from this structure to insert a call to the assembly language function
-'sigdelayed' in place of the main thread's normal return address. So,
-when a call to (e.g.) _read returns after detecting a signal, it does
-not return to its caller. Rather, it returns to sigdelayed.
-
-The sigdelayed function saves a lot of state on the stack and sets the
-signal mask as appropriate for POSIX. It uses information from the
-sigsave structure which has been filled in by interrupt_on_return, as
-called by setup_handler. sigdelayed pushes a "call" to the function
-"sigreturn" on the stack. This will be the return address seen by the
-signal handler. After setting up the return value, modifying the signal
-mask, and saving other information on the stack, sigreturn clears the
-sigsave structure (so that setup_handler can use it) and jumps to the
-signal handler function. And, so a UNIX signal handler function is
-emulated.
-
-The signal handler function operates as normal for UNIX but, upon
-return, it does not go directly back to the return address of the
-original cygwin function. Instead it returns to the previously
-mentioned 'sigreturn' assembly language function.
-
-sigreturn resets the process mask to its state prior to calling the
-signal handler. It checks to see if any new signals have come in and
-calls the handler for them now, ensuring that the order of signal
-arrival is more or less maintained. It checks to see if a cygwin
-routine has set a special "restore this errno on returning from a
-signal" value and sets errno to this, if so. Finally, it restores all
-of the register values that were in effect when sigdelayed was called.
-
-Ok, you thought I had forgotten about the 'pending' stuff didn't you?
-Well, if you can rewind up to the discussion of sig_handle, we'll return
-to the situation where sigsave was currently active. In this case,
-setup_handler will set a "pending" flag, will reincrement the appropriate
-element of the above signal array, and will return 0 to indicate that
-the interrupt did not occur. Otherwise setup_handler returns 1.
-
-For pending signals, the theory is that the signal handler thread will
-be forced to be rerun by having some strategic cygwin function call
-sig_send with a __SIGFLUSH "argument" to it. This causes the signal
-handler to rescan the signal array looking for pending signals.
-
-This leads us to the sig_send function. This is the "client side" part
-of the signal manipulation process. sig_send is the low-level function
-called by a high level process like kill(). You would use sig_send
-to send a __SIGFLUSH to the signal thread.