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.txt158
1 files changed, 0 insertions, 158 deletions
diff --git a/winsup/cygwin/how-signals-work.txt b/winsup/cygwin/how-signals-work.txt
deleted file mode 100644
index 4d94c79dc..000000000
--- a/winsup/cygwin/how-signals-work.txt
+++ /dev/null
@@ -1,158 +0,0 @@
-Copyright 2001, 2002, 2003, 2004 Red Hat Inc., Christopher Faylor
-
-[note that the following discussion is still incomplete]
-
-How do signals work?
-
-On process startup, cygwin starts a secondary thread which deals with
-signals. This thread contains a loop which blocks waiting for
-information to arrive on a pipe whose handle (sendsig) is currently
-stored in _pinfo (this may change).
-
-Communication on the sendsig pipe is via the 'sigpacket' structure.
-This structure is filled out by the sig_send function with information
-about the signal being sent, such as (as of this writing) the signal
-number, the originating pid, the originating thread, and the address of
-the mask to use (this may change).
-
-Any cygwin function which calls a win32 api function is wrapped by the
-assembly functions "_sigfe" and "_sigbe". These functions maintain a
-cygwin "signal stack" which is used by the signal thread to control
-handling of signal interrupts. Cygwin functions which need to be
-wrapped by these functions (the majority) are labelled by the SIGFE
-option in the file cygwin.din.
-
-The cygwin.din function is translated into a standard cygwin.def file by
-the perl script "gendef". This function notices exported cygwin
-functions which are labelled as SIGFE and generates a front end assembly
-file "sigfe.s" which contains the wrapper glue necessary for every
-function to call sigfe prior to actually dispatching to the real cygwin
-function. This generated file contains low-level signal related
-functions: _sigfe, _sigbe, sigdelayed, sigreturn, longjmp, and setjmp.
-
-The signal stack maintained by sigfe/sigbe and friends is a secondary
-shadow stack. Addresses from this stack are swapped into the "real"
-stack as needed to control program flow. The intent is that executing
-cygwin functions will still see the same stack layout as if they had
-been called directly and will be able to retrieve arguments from the
-stack but will always return to the _sigbe routine so that any signal
-handlers will be properly called.
-
-Upon receipt of a "non-special" (see below) signal, the function
-sigpacket::process is called. This function determines what action, if
-any, to take on the signal. Possible actions are: Ignore the signal
-(e.g., SIGUSR1), terminate the program (SIGKILL, SIGTERM), stop the
-program (SIGSTOP, SIGTSTP, etc.), wake up a sigwait or sigwaitinfo in a
-targetted thread, or call a signal handler (possibly in a thread). If
-no thread information has been sent to sigpacket::process, it determines
-the correct thread to use based on various heuristics, as per UNIX. As
-per linux, the only time a handler is called in a thread is when there
-is some kind of fault like SIGSEGV, SIGILL, etc. Signals sent via the
-UNIX kill() function are normally sent to the main thread. Ditto
-signals sent as the result of pressing tty keys, like CTRL-C.
-
-Signals which stop a process are handled by a special internal handler:
-sig_handle_tty_stop. Some signals (e.g., SIGKILL, SIGSTOP) are
-uncatchable, 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, a standard UNIX sigaction structure, and a pointer to the
-thread's "_cygtls" information. The meat of signal processing is in
-setup_handler.
-
-setup_handler has a "simple" task. It tries to stop the appropriate
-thread and either redirect its execution to the signal handler function,
-flag that a signal has been received (sigwait) or both (sigpause).
-
-To accomplish its task, setup_handler first inspects the target thread's
-local storage (_cygtls) 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 target thread. If this
-structure seems to be "active", then setup_handler returns, notifying it's
-parent via a false value. Otherwise processing continues.
-
-(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. This causes the signal handler to
-rescan the signal array looking for pending signals.)
-
-After determining that it's ok to send a signal, setup_handler will lock
-the cygtls stack to ensure that it has complete access. It will then
-inspect the thread's 'incyg' boolean. If this is true, the thread is
-currently executing a cygwin function. If it is false, the thread is
-unlocked and it is assumed that the thread is executing "user" code.
-The actions taken by setup_handler differ based on whether the program
-is executing a cygwin routine or not.
-
-If the program is executing a cygwin routine, then the
-interrupt_on_return function is called which causes the address of the
-'sigdelayed' function to be pushed onto the thread's signal stack, and
-the signal's mask and handler to be saved in the tls structure. After
-performing these operations, the 'signal_arrived' event is signalled, as
-well as any thread-specific wait event.
-
-Since the sigdelayed function was saved on the thread's signal stack,
-when the cygwin function returns, it will eventually return to the
-sigdelayed "front end". The sigdelayed function will save a lot of
-state on the stack and set the signal mask as appropriate for POSIX.
-It uses information from the _cygtls structure which has been filled in
-by interrupt_setup, as called by setup_handler. sigdelayed pushes a
-"call" to the function "sigreturn" on the thread's signal stack. This
-will be the return address eventually 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 signal number in the
-_cygtls 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 a cygwin routine has set a special
-"restore this errno on returning from a signal" value and sets errno to
-this, if so. It pops the signal stack, places the new return address on
-the real stack, restores all of the register values that were in effect
-when sigdelayed was called, and then returns.
-
-Ok. That is more or less how cygwin interrupts a process which is
-executing a cygwin function. We are almost ready to talk about how
-cygwin interrupts user code but there is one more thing to talk about:
-SA_RESTART.
-
-UNIX allows some blocking functions to be interrupted by a signal
-handler and then return to blocking. In cygwin, so far, only
-read/readv() and the wait* functions operate in this fashion. To
-accommodate this behavior, a function notices when a signal comes in and
-then calls the _cygtls function 'call_signal_handler_now'.
-'call_signal_handler_now' emulates the behavior of both sigdelayed and
-sigreturn. It sets the appropriate masks and calls the handler,
-returning true to the caller if SA_RESTART is active. If SA_RESTART is
-active, the function will loop. Otherwise it will typically return -1
-and set the errno to EINTR.
-
-Phew. So, now we turn to the case where cygwin needs to interrupt the
-program when it is not executing a cygwin function. In this scenario,
-we rely on the win32 "SuspendThread" function. Cygwin will suspend the
-thread using this function and then inspect the location at which the
-thread is executing using the win32 "GetThreadContext" call. In theory,
-the program should not be executing in a win32 api since attempts to
-suspend a process executing a win32 call can cause disastrous results,
-especially on Win9x.
-
-If the process is executing in an unsafe location then setup_handler
-will (quickly!) return false as in the case above. Otherwise, the
-current location of the thread is pushed on the thread's signal stack
-and the thread is redirected to the sigdelayed function via the win32
-"SetThreadContext" call. Then the thread is restarted using the win32
-"ResumeThread" call and things proceed as per the sigdelayed discussion
-above.
-
-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() or pthread_kill().
-
-** More to come **