[tor-commits] [stem/master] Close stdout/stderr after the tor process initializes
atagar at torproject.org
atagar at torproject.org
Sat May 31 19:08:36 UTC 2014
commit fcf49ad8afe52a36553fabbeaa3741566fa299f6
Author: Damian Johnson <atagar at torproject.org>
Date: Thu May 29 08:48:51 2014 -0700
Close stdout/stderr after the tor process initializes
We use tor's stdout and stderr to determine two things...
* at what stage it has bootstrapped to
* errors if tor fails to start
After startup, however, we stop listing to stdout which can cause Tor to lock
up if it's registering a lot of NOTICE level messages...
https://trac.torproject.org/projects/tor/ticket/9862
Tested by the following script. Before this fix tor hung after ~3 seconds. With
it things happily chug along...
import time
import stem.process
from stem.control import EventType, Controller
tor_process = stem.process.launch_tor_with_config(
config = {
'ControlPort': '9051',
'Log': 'DEBUG stdout',
},
take_ownership = True,
)
with Controller.from_port() as controller:
controller.authenticate()
def heartbeat(event):
print "%s - %s / %s" % (time.time(), event.read, event.written)
controller.add_event_listener(heartbeat, EventType.BW)
print "Press any key to quit..."
raw_input()
---
docs/change_log.rst | 7 ++++---
stem/process.py | 3 +++
test/integ/process.py | 2 +-
test/runner.py | 2 +-
4 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/docs/change_log.rst b/docs/change_log.rst
index 6b71913..279f2bb 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -52,9 +52,10 @@ The following are only available within Stem's `git repository
* Added `support for TB_EMPTY events <api/response.html#stem.response.events.TokenBucketEmptyEvent>`_ (:spec:`6f2919a`)
* Added `support for HS_DESC events <api/response.html#stem.response.events.HSDescEvent>`_ (:spec:`a67ac4d`, :trac:`10807`)
* Changed :func:`~stem.control.Controller.get_network_status` and :func:`~stem.control.Controller.get_network_statuses` to provide :class:`~stem.descriptor.router_status_entry.RouterStatusEntryMicroV3` if Tor is using microdescriptors (:trac:`7646`)
- * The :func:`~stem.connection.connect_port` and :func:`~stem.connection.connect_socket_file` didn't properly mark the Controller it returned as being authenticated, causing event listening among other things to fail.
- * The :func:`~stem.control.Controller.add_event_listener` method couldn't accept event types that Stem didn't already recognize.
- * The :class:`~stem.exit_policy.ExitPolicy` class couldn't be pickled.
+ * The :func:`~stem.connection.connect_port` and :func:`~stem.connection.connect_socket_file` didn't properly mark the Controller it returned as being authenticated, causing event listening among other things to fail
+ * The :func:`~stem.control.Controller.add_event_listener` method couldn't accept event types that Stem didn't already recognize
+ * The :class:`~stem.exit_policy.ExitPolicy` class couldn't be pickled
+ * Tor instances spawned with :func:`~stem.process.launch_tor` and :func:`~stem.process.launch_tor_with_config` could hang due to unread stdout content, we now close stdout and stderr once tor finishes bootstrapping (:trac:`9862`)
* **Descriptors**
diff --git a/stem/process.py b/stem/process.py
index ad05659..c9fe863 100644
--- a/stem/process.py
+++ b/stem/process.py
@@ -159,6 +159,9 @@ def launch_tor(tor_cmd = 'tor', args = None, torrc_path = None, completion_perce
if timeout:
signal.alarm(0) # stop alarm
+ tor_process.stdout.close()
+ tor_process.stderr.close()
+
if temp_file:
try:
os.remove(temp_file)
diff --git a/test/integ/process.py b/test/integ/process.py
index d87dda4..b06e500 100644
--- a/test/integ/process.py
+++ b/test/integ/process.py
@@ -65,7 +65,7 @@ class TestProcess(unittest.TestCase):
control_socket.close()
tor_process.kill()
- tor_process.communicate()
+ tor_process.wait()
def test_launch_tor_with_timeout(self):
"""
diff --git a/test/runner.py b/test/runner.py
index 3ad78f2..07cbd34 100644
--- a/test/runner.py
+++ b/test/runner.py
@@ -349,7 +349,7 @@ class Runner(object):
except OSError:
pass
- self._tor_process.communicate() # blocks until the process is done
+ self._tor_process.wait() # blocks until the process is done
# if we've made a temporary data directory then clean it up
if self._test_dir and CONFIG['integ.test_directory'] == '':
More information about the tor-commits
mailing list