Commit 59029e83 authored by Jason Madden's avatar Jason Madden

The PyPy patch for the main thread is applicable anywhere that the stdlib...

The PyPy patch for the main thread is applicable anywhere that the stdlib threading module was imported before monkey patching. Fixes #153
parent aee866b0
......@@ -41,6 +41,11 @@ Unreleased
"HTTP 400 bad request" responses instead of a 500 error or, in the
worst case, a server-side hang. Reported in :issue:`229` by Björn
Lindqvist.
- Importing the standard library ``threading`` module *before* using
``gevent.monkey.patch_all()`` no longer causes Python 3.4 to fail to
get the ``repr`` of the main thread, and other CPython platforms to
return an unjoinable DummyThread. (Note that this is not
recommended.) Reported in :issue:`153`.
1.1a2 (Jul 8, 2015)
===================
......
......@@ -175,7 +175,7 @@ def patch_thread(threading=True, _threading_local=True, Event=False):
if threading.current_thread() == threading.main_thread():
main_thread = threading.main_thread()
_greenlet = main_thread._greenlet = greenlet.getcurrent()
from .hub import sleep
from gevent.hub import sleep
def join(timeout=None):
if threading.current_thread() is main_thread:
......
......@@ -36,14 +36,15 @@ class _DummyThread(_DummyThread_):
def _Thread__stop(self):
pass
if PYPY:
# Make sure the MainThread can be found by our current greenlet ID,
# otherwise we get a new DummyThread, which cannot be joined.
# Fixes tests in test_threading_2
if _get_ident() not in __threading__._active and len(__threading__._active) == 1:
k, v = next(iter(__threading__._active.items()))
del __threading__._active[k]
__threading__._active[_get_ident()] = v
# Make sure the MainThread can be found by our current greenlet ID,
# otherwise we get a new DummyThread, which cannot be joined.
# Fixes tests in test_threading_2 under PyPy, and generally makes things nicer
# when threading is imported before monkey patching
# XXX: This assumes that the import is happening in the "main" greenlet
if _get_ident() not in __threading__._active and len(__threading__._active) == 1:
k, v = next(iter(__threading__._active.items()))
del __threading__._active[k]
__threading__._active[_get_ident()] = v
import sys
if sys.version_info[:2] >= (3, 4):
......@@ -86,6 +87,12 @@ if sys.version_info[:2] >= (3, 4):
__implements__.append('Thread')
# The main thread is patched up with more care in monkey.py
#t = __threading__.current_thread()
#if isinstance(t, __threading__.Thread):
# t.__class__ = Thread
# t._greenlet = getcurrent()
if sys.version_info[:2] >= (3, 3):
__implements__.remove('_get_ident')
__implements__.append('get_ident')
......
# If stdlib threading is imported *BEFORE* monkey patching,
# we can still get the current (main) thread, and it's not a DummyThread.
import threading
from gevent import monkey
monkey.patch_all()
import greentest
class Test(greentest.TestCase):
def test_main_thread(self):
current = threading.current_thread()
self.assertFalse(isinstance(current, threading._DummyThread))
self.assertTrue(isinstance(current, monkey.get_original('threading', 'Thread')))
# in 3.4, if the patch is incorrectly done, getting the repr
# of the thread fails
repr(current)
if __name__ == '__main__':
greentest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment