diff options
| author | bwarsaw | 2006-12-29 22:20:25 +0000 |
|---|---|---|
| committer | bwarsaw | 2006-12-29 22:20:25 +0000 |
| commit | f4a456a83b630feb294724ab462c87ca1ce1c3ae (patch) | |
| tree | c5c88540dae8306d11671f603d8975b01803ea16 /scripts/driver | |
| parent | ae185106a624bfa7888aa8722d35194d3c5150e8 (diff) | |
| download | mailman-f4a456a83b630feb294724ab462c87ca1ce1c3ae.tar.gz mailman-f4a456a83b630feb294724ab462c87ca1ce1c3ae.tar.zst mailman-f4a456a83b630feb294724ab462c87ca1ce1c3ae.zip | |
Diffstat (limited to 'scripts/driver')
| -rw-r--r-- | scripts/driver | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/scripts/driver b/scripts/driver index 4cf182dd4..458e891a7 100644 --- a/scripts/driver +++ b/scripts/driver @@ -98,6 +98,8 @@ def run_main(): pkg = __import__('Mailman.Cgi', globals(), locals(), [scriptname]) module = getattr(pkg, scriptname) main = getattr(module, 'main') + import signal + signal.signal(signal.SIGTERM, sigterm_handler) try: try: sys.stdout = tempstdout @@ -197,6 +199,7 @@ def print_environment(log=None): print >> outfp, 'sys.exec_prefix =', sys.exec_prefix print >> outfp, 'sys.path =', sys.exec_prefix print >> outfp, 'sys.platform =', sys.platform + print >> outfp, 'args =', SPACE.join(sys.argv) # Write the same information to the HTML sink. if not STEALTH_MODE: @@ -275,3 +278,37 @@ useful traceback for you. Please report this to the Mailman administrator at this site. """ print >> sys.__stderr__, '[Mailman: low level unrecoverable exception]' + + + +# Signal handler to guarantee that, when running under traditional CGI, a +# locked mailing list will be unlocked when a fatal signal is received. +# +# try/finally isn't enough because of this scenario: user hits a CGI page +# which may take a long time to render; user gets bored and hits the browser's +# STOP button; browser shuts down socket; server tries to write to broken +# socket and gets a SIGPIPE. Under Apache 1.3/mod_cgi, Apache catches this +# SIGPIPE (I presume it is buffering output from the cgi script), then turns +# around and SIGTERMs the cgi process. Apache waits three seconds and then +# SIGKILLs the cgi process. We /must/ catch the SIGTERM and do the most +# reasonable thing we can in as short a time period as possible. If we get +# the SIGKILL we're screwed because it's uncatchable and we'll have no +# opportunity to clean up after ourselves. +# +# This signal handler catches the SIGTERM, unlocks the list, and then +# exits the process. The effect of this is that the changes made to the +# MailList object will be aborted, which seems like the only sensible +# semantics. +# +# Note that we must not install this signal handler when running under the +# HTTPRunner wsgi server because the sys.exit(0) will cause the supervisor +# mailmanctl process to restart the HTTPRunner. When running in that +# environment, just let the normal signal handling do the right thing. +def sigterm_handler(signum, frame, mlist=mlist): + # Make sure the list gets unlocked... + if mlist.Locked(): + mlist.Unlock() + # ...and ensure we exit, otherwise race conditions could cause us to + # enter MailList.Save() while we're in the unlocked state, and that + # could be bad! + sys.exit(0) |
