From 396ec8c8601319073c0f9b7fb95bf44c4a4fa6f4 Mon Sep 17 00:00:00 2001 From: "hinoka@chromium.org" Date: Mon, 17 Sep 2012 20:41:49 +0000 Subject: Sharding supervisor changes * Fixed tests in windows * Split up stdout and stderr so they print separately Its not clear whether or not this'll fix http://code.google.com/p/chromium/issues/detail?id=145308&can=3&colspec=ID%20Pri%20Mstone%20ReleaseBlock%20OS%20Area%20Feature%20Status%20Owner%20Summary But the goal is to quarantine stderr from mixing in with the stdout pipe, so this code uses two extra threads per shard to collect stdout and stderr byte by byte, and emit them line by line. Review URL: https://chromiumcodereview.appspot.com/10919228 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157184 0039d316-1c4b-4281-b951-d872f2087c98 --- tools/sharding_supervisor/stdio_buffer.py | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tools/sharding_supervisor/stdio_buffer.py (limited to 'tools/sharding_supervisor/stdio_buffer.py') diff --git a/tools/sharding_supervisor/stdio_buffer.py b/tools/sharding_supervisor/stdio_buffer.py new file mode 100644 index 0000000..737374d --- /dev/null +++ b/tools/sharding_supervisor/stdio_buffer.py @@ -0,0 +1,60 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Syncronized Standard IO Linebuffer implemented with cStringIO.""" + +import cStringIO +import os +import sys +import threading +import Queue + + +class StdioBuffer(object): + def __init__(self, shard): + self.line_ready_event = threading.Event() + self.queue = Queue.Queue() + self.lock = threading.Lock() + self.completed = 0 + self.shard = shard + + def _pipe_handler(self, system_pipe, program_pipe): + """Helper method for collecting stdio output. Output is collected until + a newline is seen, at which point an event is triggered and the line is + pushed to a buffer as a (stdio, line) tuple.""" + buffer = cStringIO.StringIO() + pipe_running = True + while pipe_running: + char = program_pipe.read(1) + if not char and self.shard.poll() is not None: + pipe_running = False + self.line_ready_event.set() + buffer.write(char) + if char == '\n' or not pipe_running: + line = buffer.getvalue() + if not line and not pipe_running: + with self.lock: + self.completed += 1 + self.line_ready_event.set() + break + self.queue.put((system_pipe, line)) + self.line_ready_event.set() + buffer.close() + buffer = cStringIO.StringIO() + + def handle_pipe(self, system_pipe, program_pipe): + t = threading.Thread(target=self._pipe_handler, args=[system_pipe, + program_pipe]) + t.start() + return t + + def readline(self): + """Emits a tuple of (sys.stderr, line) or (sys.stdout, line). This is a + blocking call.""" + while self.completed < 2 and self.queue.empty(): + self.line_ready_event.wait() + self.line_ready_event.clear() + if not self.queue.empty(): + return self.queue.get_nowait() + else: + return (None, None) \ No newline at end of file -- cgit v1.1