You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.6 KiB
Python
93 lines
2.6 KiB
Python
5 years ago
|
"""
|
||
|
Tests specifically for the monkey-patched threading module.
|
||
|
"""
|
||
|
from gevent import monkey; monkey.patch_all() # pragma: testrunner-no-monkey-combine
|
||
|
import gevent.hub
|
||
|
|
||
|
# check that the locks initialized by 'threading' did not init the hub
|
||
|
assert gevent.hub._get_hub() is None, 'monkey.patch_all() should not init hub'
|
||
|
|
||
|
import gevent
|
||
|
import gevent.testing as greentest
|
||
|
import threading
|
||
|
|
||
|
|
||
|
def helper():
|
||
|
threading.currentThread()
|
||
|
gevent.sleep(0.2)
|
||
|
|
||
|
|
||
|
class TestCleanup(greentest.TestCase):
|
||
|
|
||
|
def _do_test(self, spawn):
|
||
|
before = len(threading._active)
|
||
|
g = spawn(helper)
|
||
|
gevent.sleep(0.1)
|
||
|
self.assertEqual(len(threading._active), before + 1)
|
||
|
try:
|
||
|
g.join()
|
||
|
except AttributeError:
|
||
|
while not g.dead:
|
||
|
gevent.sleep()
|
||
|
# Raw greenlet has no join(), uses a weakref to cleanup.
|
||
|
# so the greenlet has to die. On CPython, it's enough to
|
||
|
# simply delete our reference.
|
||
|
del g
|
||
|
# On PyPy, it might take a GC, but for some reason, even
|
||
|
# running several GC's doesn't clean it up under 5.6.0.
|
||
|
# So we skip the test.
|
||
|
#import gc
|
||
|
#gc.collect()
|
||
|
|
||
|
self.assertEqual(len(threading._active), before)
|
||
|
|
||
|
|
||
|
def test_cleanup_gevent(self):
|
||
|
self._do_test(gevent.spawn)
|
||
|
|
||
|
@greentest.skipOnPyPy("weakref is not cleaned up in a timely fashion")
|
||
|
def test_cleanup_raw(self):
|
||
|
self._do_test(gevent.spawn_raw)
|
||
|
|
||
|
|
||
|
class TestLockThread(greentest.TestCase):
|
||
|
|
||
|
def _spawn(self, func):
|
||
|
t = threading.Thread(target=func)
|
||
|
t.start()
|
||
|
return t
|
||
|
|
||
|
def test_spin_lock_switches(self):
|
||
|
# https://github.com/gevent/gevent/issues/1464
|
||
|
lock = threading.Lock()
|
||
|
lock.acquire()
|
||
|
spawned = []
|
||
|
|
||
|
def background():
|
||
|
spawned.append(True)
|
||
|
while 1:
|
||
|
# blocking= in Py3, wait (no default, no name) in Py2
|
||
|
if lock.acquire(False):
|
||
|
break
|
||
|
|
||
|
thread = threading.Thread(target=background)
|
||
|
# If lock.acquire(False) doesn't yield when it fails,
|
||
|
# then this never returns.
|
||
|
thread.start()
|
||
|
# Verify it tried to run
|
||
|
self.assertEqual(spawned, [True])
|
||
|
# We can attempt to join it, which won't work.
|
||
|
thread.join(0)
|
||
|
# We can release the lock and then it will acquire.
|
||
|
lock.release()
|
||
|
thread.join()
|
||
|
|
||
|
|
||
|
class TestLockGreenlet(TestLockThread):
|
||
|
|
||
|
def _spawn(self, func):
|
||
|
return gevent.spawn(func)
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
greentest.main()
|