Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1220)

Unified Diff: subprocess2.py

Issue 8808002: Using lists is faster than cStringIO. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/subprocess2_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: subprocess2.py
diff --git a/subprocess2.py b/subprocess2.py
index 3ad804791fcabb0b423be212f31ef16c5d060064..ef95d6f8701c4c7634782e8729e89fab1c07dd44 100644
--- a/subprocess2.py
+++ b/subprocess2.py
@@ -173,25 +173,22 @@ class Popen(subprocess.Popen):
self.stdout_cb = None
self.stderr_cb = None
- self.stdout_void = False
- self.stderr_void = False
- def fix(stream):
+ self.stdin_is_void = False
+ self.stdout_is_void = False
+ self.stderr_is_void = False
+
+ if kwargs.get('stdin') is VOID:
+ kwargs['stdin'] = open(os.devnull, 'r')
+ self.stdin_is_void = True
+
+ for stream in ('stdout', 'stderr'):
if kwargs.get(stream) in (VOID, os.devnull):
- # Replaces VOID with handle to /dev/null.
- # Create a temporary file to workaround python's deadlock.
- # http://docs.python.org/library/subprocess.html#subprocess.Popen.wait
- # When the pipe fills up, it will deadlock this process. Using a real
- # file works around that issue.
kwargs[stream] = open(os.devnull, 'w')
- setattr(self, stream + '_void', True)
+ setattr(self, stream + '_is_void', True)
if callable(kwargs.get(stream)):
- # Callable stdout/stderr should be used only with call() wrappers.
setattr(self, stream + '_cb', kwargs[stream])
kwargs[stream] = PIPE
- fix('stdout')
- fix('stderr')
-
self.start = time.time()
self.timeout = None
self.shell = kwargs.get('shell', None)
@@ -288,6 +285,9 @@ class Popen(subprocess.Popen):
target=_queue_pipe_read, args=(self.stderr, 'stderr'))
if input:
threads['stdin'] = threading.Thread(target=write_stdin)
+ elif self.stdin:
+ # Pipe but no input, make sure it's closed.
+ self.stdin.close()
for t in threads.itervalues():
t.start()
@@ -346,20 +346,19 @@ class Popen(subprocess.Popen):
stderr = None
# Convert to a lambda to workaround python's deadlock.
# http://docs.python.org/library/subprocess.html#subprocess.Popen.wait
- # When the pipe fills up, it will deadlock this process. Using a thread
- # works around that issue. No need for thread safe function since the call
- # backs are guaranteed to be called from the main thread.
- if self.stdout and not self.stdout_cb and not self.stdout_void:
- stdout = cStringIO.StringIO()
- self.stdout_cb = stdout.write
- if self.stderr and not self.stderr_cb and not self.stderr_void:
- stderr = cStringIO.StringIO()
- self.stderr_cb = stderr.write
+ # When the pipe fills up, it would deadlock this process.
+ if self.stdout and not self.stdout_cb and not self.stdout_is_void:
+ stdout = []
+ self.stdout_cb = stdout.append
+ if self.stderr and not self.stderr_cb and not self.stderr_is_void:
+ stderr = []
+ self.stderr_cb = stderr.append
self._tee_threads(input)
- if stdout:
- stdout = stdout.getvalue()
- if stderr:
- stderr = stderr.getvalue()
+ if stdout is not None:
+ stdout = ''.join(stdout)
+ stderr = None
+ if stderr is not None:
+ stderr = ''.join(stderr)
return (stdout, stderr)
@@ -374,17 +373,16 @@ def communicate(args, timeout=None, **kwargs):
"""
stdin = kwargs.pop('stdin', None)
if stdin is not None:
- if stdin is VOID:
- kwargs['stdin'] = open(os.devnull, 'r')
- stdin = None
- else:
- assert isinstance(stdin, basestring)
+ if isinstance(stdin, basestring):
# When stdin is passed as an argument, use it as the actual input data and
# set the Popen() parameter accordingly.
kwargs['stdin'] = PIPE
+ else:
+ kwargs['stdin'] = stdin
+ stdin = None
proc = Popen(args, **kwargs)
- if stdin not in (None, VOID):
+ if stdin:
return proc.communicate(stdin, timeout), proc.returncode
else:
return proc.communicate(None, timeout), proc.returncode
« no previous file with comments | « no previous file | tests/subprocess2_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698