OLD | NEW |
| (Empty) |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 """Syncronized Standard IO Linebuffer implemented with cStringIO.""" | |
5 | |
6 import cStringIO | |
7 import threading | |
8 import Queue | |
9 | |
10 | |
11 class StdioBuffer(object): | |
12 def __init__(self, shard): | |
13 self.queue = Queue.Queue() | |
14 self.completed = 0 | |
15 self.shard = shard | |
16 | |
17 def _pipe_handler(self, system_pipe, program_pipe): | |
18 """Helper method for collecting stdio output. Output is collected until | |
19 a newline is seen, at which point an event is triggered and the line is | |
20 pushed to a buffer as a (stdio, line) tuple.""" | |
21 buf = cStringIO.StringIO() | |
22 pipe_running = True | |
23 while pipe_running: | |
24 char = program_pipe.read(1) | |
25 if not char and self.shard.poll() is not None: | |
26 pipe_running = False | |
27 buf.write(char) | |
28 if char == '\n' or not pipe_running: | |
29 line = buf.getvalue() | |
30 if line: | |
31 self.queue.put((system_pipe, line)) | |
32 if not pipe_running: | |
33 self.queue.put((system_pipe, None)) | |
34 buf.close() | |
35 buf = cStringIO.StringIO() | |
36 | |
37 def handle_pipe(self, system_pipe, program_pipe): | |
38 t = threading.Thread(target=self._pipe_handler, args=[system_pipe, | |
39 program_pipe]) | |
40 t.start() | |
41 return t | |
42 | |
43 def readline(self): | |
44 """Emits a tuple of (sys.stderr, line), (sys.stdout, line), or (None, None) | |
45 if the process has finished. This is a blocking call.""" | |
46 while True: | |
47 (pipe, line) = self.queue.get(True) | |
48 if line: | |
49 return (pipe, line) | |
50 self.completed += 1 | |
51 if self.completed >= 2: | |
52 return (None, None) | |
OLD | NEW |