Figure out what to do about zope.sendmail incompatibility with Python >= 2.5.1

Bug #413335 reported by Max Bowsher on 2009-08-13
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Launchpad itself
Gary Poster
Fix Released
Gary Poster

Bug Description

After changes to the design of Python threading in 2.5.1,'s background thread no longer exits at Python exit time, and causes the Python process to hang and require kill -9. There is no upstream solution AFAICS.


Need to liase with upstream and figure out what on earth to do here.

Changed in launchpad-foundations:
importance: Undecided → High
milestone: none → 3.0
status: New → Triaged
Gary Poster (gary) wrote :

Max, have you asked upstream about this, or shall I?

Max Bowsher (maxb) wrote :

I have not yet.

I should probably write up a fuller description of the problem, and some test programs.

Max Bowsher (maxb) wrote :

Description of the situation:

Prior to Python 2.5.1, the atexit handlers were executed when the *main* thread exits. However, was then filed, the essence of which is that the atexit handlers could tear down cross-thread resources that were still in use by other threads.

For this reason, the shutdown procedure was modified in Python 2.5.1 - now, when the main thread exits, it first makes a private call to threading._shutdown(), which waits until all non-daemon threads have exited, and *only then* proceeds to run the atexit handlers.

Herein lies the problem. attempts to use atexit to notify itself when it should shut down. However, the Python runtime >= 2.5.1 will wait for the QueueProcessorThread to exit before it calls the atexit handlers!

Potential solutions:

(1) To gain behaviour most similar to earlier Python versions, an evil monkeypatch into Python internals like this: works.

(2) Make the QueueProcessorThread a daemon thread. It will be terminated without notification when the interpreter exits, but the current QueueProcessorThread does not attempt to ensure its queue is completely flushed before shutdown anyway, so that should not matter.

I will attach a small Python demo program useful for illustrating and exploring the issue.

Max Bowsher (maxb) wrote :
Gary Poster (gary) wrote :

This patch works from Max's experiments to use the setDaemon approach. This seems like the right basic idea--really, the current zope.sendmail code is essentially acting like a daemon thread, with the combination of atexit and the _stopped flag simply trying to make the loop's block run as a unit before the thread can exit.

Therefore, I made the thread a daemon. Reviewing the code, it seemed the only point at which the code would not fail cleanly was after the mail was sent and before the msg was removed--a single block of actions. Therefore, as I described in the comment, I tried to tie those two actions together with a lock.

When the atexit code has to wait for the lock, the process no longer dies for some reason: the daemon flag is no longer honored in that case. Therefore, I continue to use the _stopped flag for communication in that case. The _stopped flag is set before the lock is acquired.

I also changed __stopped to _stopped because I generally don't like the Python mangled name game.

Marius Gedminas and Max have both reviewed this patch. I may try to get Francis Lacoste to also review, I'll verify it works in Launchpad, and then I plan to push it upstream and make a release today or tomorrow. I intend to make it a bugfix release of zope.sendmail: 3.5.2.

affects: zope3 → zope.sendmail
Changed in zope.sendmail:
status: New → In Progress
Changed in launchpad-foundations:
status: Triaged → In Progress
Changed in zope.sendmail:
importance: Undecided → Low
assignee: nobody → Gary Poster (gary)
Changed in launchpad-foundations:
assignee: nobody → Gary Poster (gary)
Gary Poster (gary) on 2009-09-15
Changed in launchpad-foundations:
status: In Progress → Fix Committed
Changed in zope.sendmail:
status: In Progress → Fix Released
Curtis Hovey (sinzui) on 2009-11-11
Changed in launchpad-foundations:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.