]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Add Subprocess.wait_for_exit, a coro-friendly set_exit_callback().
authorBen Darnell <ben@bendarnell.com>
Fri, 27 Mar 2015 03:36:43 +0000 (23:36 -0400)
committerBen Darnell <ben@bendarnell.com>
Fri, 27 Mar 2015 03:36:43 +0000 (23:36 -0400)
Fixes #1391.

tornado/process.py
tornado/test/process_test.py

index 3790ca0a55f99c591f02aabe18a9acdd9a2f2afc..fb9254fc0314cbf7c0b2d8f2378435c9728b8a5f 100644 (file)
@@ -29,6 +29,7 @@ import time
 
 from binascii import hexlify
 
+from tornado.concurrent import Future
 from tornado import ioloop
 from tornado.iostream import PipeIOStream
 from tornado.log import gen_log
@@ -258,6 +259,22 @@ class Subprocess(object):
         Subprocess._waiting[self.pid] = self
         Subprocess._try_cleanup_process(self.pid)
 
+    def wait_for_exit(self):
+        """Returns a `.Future` which resolves when the process exits.
+
+        Usage::
+
+            ret = yield proc.wait_for_exit()
+
+        This is a coroutine-friendly alternative to `set_exit_callback`
+        (and a replacement for the blocking `subprocess.Popen.wait`).
+
+        .. versionadded:: 4.2
+        """
+        future = Future()
+        self.set_exit_callback(future.set_result)
+        return future
+
     @classmethod
     def initialize(cls, io_loop=None):
         """Initializes the ``SIGCHLD`` handler.
index de727607ac85d15178196e9bd0c53fc092c9cab6..6abfabd284489b0aca3c8330f76b76c0a98a32a6 100644 (file)
@@ -13,7 +13,7 @@ from tornado.ioloop import IOLoop
 from tornado.log import gen_log
 from tornado.process import fork_processes, task_id, Subprocess
 from tornado.simple_httpclient import SimpleAsyncHTTPClient
-from tornado.testing import bind_unused_port, ExpectLog, AsyncTestCase
+from tornado.testing import bind_unused_port, ExpectLog, AsyncTestCase, gen_test
 from tornado.test.util import unittest, skipIfNonUnix
 from tornado.web import RequestHandler, Application
 
@@ -200,6 +200,16 @@ class SubprocessTest(AsyncTestCase):
         self.assertEqual(ret, 0)
         self.assertEqual(subproc.returncode, ret)
 
+    @gen_test
+    def test_sigchild_future(self):
+        skip_if_twisted()
+        Subprocess.initialize()
+        self.addCleanup(Subprocess.uninitialize)
+        subproc = Subprocess([sys.executable, '-c', 'pass'])
+        ret = yield subproc.wait_for_exit()
+        self.assertEqual(ret, 0)
+        self.assertEqual(subproc.returncode, ret)
+
     def test_sigchild_signal(self):
         skip_if_twisted()
         Subprocess.initialize(io_loop=self.io_loop)