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.

Author Tamas.K
Recipients Tamas.K
Date 2013-08-22.13:56:37
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1377179797.68.0.40345735309.issue18808@psf.upfronthosting.co.za>
In-reply-to
Content
When a thread is started in CPython, t_bootstrap [Modules/threadmodule.c] creates a PyThreadState object and then calls Thread.__bootstrap_inner [Lib/threading.py] which calls Thread.run, protected with self.__block, a Condition. Thread.join uses the same __block to block until Thread.run finished.

When Thread.run finished, __bootstrap_inner notifies on __block, so join will return. Here lies a race condition, if a thread switch to Thread.join occures before __bootstrap_inner returns to t_bootstrap. Then join will return before the PyThreadState for the thread is destroyed by t_bootstrap.

It is mostly harmless for general use, as __bootstrap_inner eventually gets scheduled again and PyThreadState is taken care of.

However. Py_EndInterpreter [Python/pythonrun.c] can be called when only the main interpreter thread is running. So when we want to call Py_EndInterpreter, we signal every other thread to stop, and join them. And when Thread.join returns, we call Py_EndInterpreter. Py_EndInterpreter checks if there are any other PyThreadStates still around and does a Py_FatalError.

As a workaround, we now do a sleep after join.
History
Date User Action Args
2013-08-22 13:56:37Tamas.Ksetrecipients: + Tamas.K
2013-08-22 13:56:37Tamas.Ksetmessageid: <1377179797.68.0.40345735309.issue18808@psf.upfronthosting.co.za>
2013-08-22 13:56:37Tamas.Klinkissue18808 messages
2013-08-22 13:56:37Tamas.Kcreate