| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Generic utils.""" | 5 """Generic utils.""" |
| 6 | 6 |
| 7 import codecs | 7 import codecs |
| 8 import cStringIO |
| 8 import logging | 9 import logging |
| 9 import os | 10 import os |
| 10 import pipes | 11 import pipes |
| 11 import Queue | 12 import Queue |
| 12 import re | 13 import re |
| 13 import stat | 14 import stat |
| 14 import subprocess | 15 import subprocess |
| 15 import sys | 16 import sys |
| 16 import tempfile | 17 import tempfile |
| 17 import threading | 18 import threading |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 of the subprocess2's output. Each line has the trailing newline | 422 of the subprocess2's output. Each line has the trailing newline |
| 422 character trimmed. | 423 character trimmed. |
| 423 stdout: Can be any bufferable output. | 424 stdout: Can be any bufferable output. |
| 424 retry: If the process exits non-zero, sleep for a brief interval and try | 425 retry: If the process exits non-zero, sleep for a brief interval and try |
| 425 again, up to RETRY_MAX times. | 426 again, up to RETRY_MAX times. |
| 426 | 427 |
| 427 stderr is always redirected to stdout. | 428 stderr is always redirected to stdout. |
| 428 """ | 429 """ |
| 429 assert print_stdout or filter_fn | 430 assert print_stdout or filter_fn |
| 430 stdout = stdout or sys.stdout | 431 stdout = stdout or sys.stdout |
| 432 output = cStringIO.StringIO() |
| 431 filter_fn = filter_fn or (lambda x: None) | 433 filter_fn = filter_fn or (lambda x: None) |
| 432 | 434 |
| 433 sleep_interval = RETRY_INITIAL_SLEEP | 435 sleep_interval = RETRY_INITIAL_SLEEP |
| 434 run_cwd = kwargs.get('cwd', os.getcwd()) | 436 run_cwd = kwargs.get('cwd', os.getcwd()) |
| 435 for _ in xrange(RETRY_MAX + 1): | 437 for _ in xrange(RETRY_MAX + 1): |
| 436 kid = subprocess2.Popen( | 438 kid = subprocess2.Popen( |
| 437 args, bufsize=0, stdout=subprocess2.PIPE, stderr=subprocess2.STDOUT, | 439 args, bufsize=0, stdout=subprocess2.PIPE, stderr=subprocess2.STDOUT, |
| 438 **kwargs) | 440 **kwargs) |
| 439 | 441 |
| 440 GClientChildren.add(kid) | 442 GClientChildren.add(kid) |
| 441 | 443 |
| 442 # Do a flush of stdout before we begin reading from the subprocess2's stdout | 444 # Do a flush of stdout before we begin reading from the subprocess2's stdout |
| 443 stdout.flush() | 445 stdout.flush() |
| 444 | 446 |
| 445 # Also, we need to forward stdout to prevent weird re-ordering of output. | 447 # Also, we need to forward stdout to prevent weird re-ordering of output. |
| 446 # This has to be done on a per byte basis to make sure it is not buffered: | 448 # This has to be done on a per byte basis to make sure it is not buffered: |
| 447 # normally buffering is done for each line, but if svn requests input, no | 449 # normally buffering is done for each line, but if svn requests input, no |
| 448 # end-of-line character is output after the prompt and it would not show up. | 450 # end-of-line character is output after the prompt and it would not show up. |
| 449 try: | 451 try: |
| 450 in_byte = kid.stdout.read(1) | 452 in_byte = kid.stdout.read(1) |
| 451 if in_byte: | 453 if in_byte: |
| 452 if call_filter_on_first_line: | 454 if call_filter_on_first_line: |
| 453 filter_fn(None) | 455 filter_fn(None) |
| 454 in_line = '' | 456 in_line = '' |
| 455 while in_byte: | 457 while in_byte: |
| 458 output.write(in_byte) |
| 459 if print_stdout: |
| 460 stdout.write(in_byte) |
| 456 if in_byte != '\r': | 461 if in_byte != '\r': |
| 457 if print_stdout: | |
| 458 stdout.write(in_byte) | |
| 459 if in_byte != '\n': | 462 if in_byte != '\n': |
| 460 in_line += in_byte | 463 in_line += in_byte |
| 461 else: | 464 else: |
| 462 filter_fn(in_line) | 465 filter_fn(in_line) |
| 463 in_line = '' | 466 in_line = '' |
| 464 else: | 467 else: |
| 465 filter_fn(in_line) | 468 filter_fn(in_line) |
| 466 in_line = '' | 469 in_line = '' |
| 467 in_byte = kid.stdout.read(1) | 470 in_byte = kid.stdout.read(1) |
| 468 # Flush the rest of buffered output. This is only an issue with | 471 # Flush the rest of buffered output. This is only an issue with |
| 469 # stdout/stderr not ending with a \n. | 472 # stdout/stderr not ending with a \n. |
| 470 if len(in_line): | 473 if len(in_line): |
| 471 filter_fn(in_line) | 474 filter_fn(in_line) |
| 472 rv = kid.wait() | 475 rv = kid.wait() |
| 473 | 476 |
| 474 # Don't put this in a 'finally,' since the child may still run if we get | 477 # Don't put this in a 'finally,' since the child may still run if we get |
| 475 # an exception. | 478 # an exception. |
| 476 GClientChildren.remove(kid) | 479 GClientChildren.remove(kid) |
| 477 | 480 |
| 478 except KeyboardInterrupt: | 481 except KeyboardInterrupt: |
| 479 print >> sys.stderr, 'Failed while running "%s"' % ' '.join(args) | 482 print >> sys.stderr, 'Failed while running "%s"' % ' '.join(args) |
| 480 raise | 483 raise |
| 481 | 484 |
| 482 if rv == 0: | 485 if rv == 0: |
| 483 return 0 | 486 return output.getvalue() |
| 484 if not retry: | 487 if not retry: |
| 485 break | 488 break |
| 486 print ("WARNING: subprocess '%s' in %s failed; will retry after a short " | 489 print ("WARNING: subprocess '%s' in %s failed; will retry after a short " |
| 487 'nap...' % (' '.join('"%s"' % x for x in args), run_cwd)) | 490 'nap...' % (' '.join('"%s"' % x for x in args), run_cwd)) |
| 488 time.sleep(sleep_interval) | 491 time.sleep(sleep_interval) |
| 489 sleep_interval *= 2 | 492 sleep_interval *= 2 |
| 490 raise subprocess2.CalledProcessError( | 493 raise subprocess2.CalledProcessError( |
| 491 rv, args, kwargs.get('cwd', None), None, None) | 494 rv, args, kwargs.get('cwd', None), None, None) |
| 492 | 495 |
| 493 | 496 |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 | 953 |
| 951 Python on OSX 10.6 raises a NotImplementedError exception. | 954 Python on OSX 10.6 raises a NotImplementedError exception. |
| 952 """ | 955 """ |
| 953 try: | 956 try: |
| 954 import multiprocessing | 957 import multiprocessing |
| 955 return multiprocessing.cpu_count() | 958 return multiprocessing.cpu_count() |
| 956 except: # pylint: disable=W0702 | 959 except: # pylint: disable=W0702 |
| 957 # Mac OS 10.6 only | 960 # Mac OS 10.6 only |
| 958 # pylint: disable=E1101 | 961 # pylint: disable=E1101 |
| 959 return int(os.sysconf('SC_NPROCESSORS_ONLN')) | 962 return int(os.sysconf('SC_NPROCESSORS_ONLN')) |
| OLD | NEW |