Commit 8e2c01fc authored by Jason Madden's avatar Jason Madden

Rework test__core_fork to run on Windows; however it shows that fork watchers aren't called there

parent f6cf7deb
......@@ -296,7 +296,7 @@
Previously the child process would hang indefinitely. Reported in
:issue:`230` by Lx Yu.
- Fork watchers are more likely to (eventually) get called in a
multi-threaded program. See :issue:`154`.
multi-threaded program (except on Windows). See :issue:`154`.
- ``gevent.killall`` accepts an arbitrary iterable for the greenlets
to kill. Reported in :issue:`404` by Martin Bachwerk; seen in
combination with older versions of simple-requests.
......
......@@ -80,7 +80,8 @@ downstream libraries, notably `gunicorn`_.
:func:`gevent.os.waitpid` (again monkey patched by default) and
:func:`gevent.signal.signal` (which is monkey patched only for the
:data:`signal.SIGCHLD` case). The latter two patches are new in 1.1.
- Fork-watchers will be called, even in multi-threaded programs.
- Fork-watchers will be called, even in multi-threaded programs
(except on Windows).
- The default threadpool and threaded resolver work in child
processes.
- File descriptors are no longer leaked if
......
......@@ -2,6 +2,7 @@ from __future__ import print_function
import gevent.monkey; gevent.monkey.patch_all()
import gevent
import os
import multiprocessing
hub = gevent.get_hub()
pid = os.getpid()
......@@ -15,10 +16,8 @@ def on_fork():
fork_watcher = hub.loop.fork(ref=False)
fork_watcher.start(on_fork)
# fork watchers weren't firing in multi-threading processes.
def run():
def run(q):
# libev only calls fork callbacks at the beginning of
# the loop; we use callbacks extensively so it takes *two*
# calls to sleep (with a timer) to actually get wrapped
......@@ -28,15 +27,25 @@ def run():
q.put(newpid)
import multiprocessing
# Use a thread to make us multi-threaded
hub.threadpool.apply(lambda: None)
q = multiprocessing.Queue()
p = multiprocessing.Process(target=run)
p.start()
p_val = q.get()
p.join()
assert p_val is not None
assert p_val != pid
def test():
# Use a thread to make us multi-threaded
hub.threadpool.apply(lambda: None)
# If the Queue is global, q.get() hangs on Windows; must pass as
# an argument.
q = multiprocessing.Queue()
p = multiprocessing.Process(target=run, args=(q,))
p.start()
p.join()
p_val = q.get()
assert p_val is not None, "The fork watcher didn't run"
assert p_val != pid
if __name__ == '__main__':
# Must call for Windows to fork properly; the fork can't be in the top-level
multiprocessing.freeze_support()
# fork watchers weren't firing in multi-threading processes.
# This test is designed to prove that they are.
# However, it fails on Windows: The fork watcher never runs!
test()
......@@ -56,6 +56,8 @@ if sys.platform == 'win32':
# other Windows-related issues (need investigating)
FAILING_TESTS += [
'test__all__.py',
# fork watchers don't get called in multithreaded programs on windows
# No idea why.
'test__core_fork.py',
'test__issues461_471.py',
'test__execmodules.py',
......
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