This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Thread.join() fails to release Lock on KeyboardInterrupt
Type: Stage:
Components: Interpreter Core Versions: Python 2.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: brett.cannon, marvinalone, phansen
Priority: normal Keywords:

Created on 2005-03-26 14:40 by phansen, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
joinfix.py phansen, 2005-03-26 15:20 snippet that works around the problem
Messages (7)
msg24801 - (view) Author: Peter Hansen (phansen) Date: 2005-03-26 14:40
In threading.Thread.join(), the Condition/Lock object
called self.__block is acquired upon entry, and
released on exit without an enclosing try/finally to
ensure that the release really occurs.

If the join() call has no timeout, the wait() call that
occurs inside can never be interrupted so there is no
problem.

If the join() call has a timeout, however, the wait()
occurs in a loop which can be interrupted by a Ctrl-C,
raising a KeyboardInterrupt which skips the
self.__block.release() call and leaves the Lock acquired.

This is a problem if the main thread (which is the only
one that will see a KeyboardInterrupt) is the one
calling join() and only if the other thread on which
the join() is being called is a non-daemon thread or,
in the case of a daemon thread, if the main thread
subsequently attempts to wait for the other thread to
terminate (for example, by monitoring isAlive() on the
other thread).

In any event, the lack of a try/finally means the
joined thread will never really finish because any
attempt by it to call its __stop() method will block
forever.
msg24802 - (view) Author: Peter Hansen (phansen) Date: 2005-03-26 15:19
Logged In: YES 
user_id=567267

A workaround (tested) is to subclass Thread and ensure that
the lock is released.  I'm not certain this is completely
safe as written, but I'm assuming that you can safely
attempt to release a lock that you don't own and the worst
that can happen is you'll get an exception (which the
workaround code catches and ignores).
msg24803 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2005-03-27 19:02
Logged In: YES 
user_id=357491

Duplicate of bug #1171023.
msg24804 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2005-03-28 00:46
Logged In: YES 
user_id=357491

That was supposed to be bug #1167930, not this bug itself.  =)
msg24805 - (view) Author: Peter Hansen (phansen) Date: 2005-03-28 12:40
Logged In: YES 
user_id=567267

I confirmed with Brett offline that this bug is indeed
distinct from #1167930 and should be reopened.
msg24806 - (view) Author: Dirk Groeneveld (marvinalone) Date: 2005-07-22 07:08
Logged In: YES 
user_id=146647

I submitted a (tested) patch for this, the id is 1240614,
the link is http://www.python.org/sf/1240614.
msg24807 - (view) Author: Peter Hansen (phansen) Date: 2007-07-28 16:43
This is fixed in Python 2.5.1 (and no doubt somewhat earlier).
History
Date User Action Args
2022-04-11 14:56:10adminsetgithub: 41762
2005-03-26 14:40:57phansencreate