| OLD | NEW |
| 1 # Copyright 2009 Google Inc. All Rights Reserved. | 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 # | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"); | 3 # found in the LICENSE file. |
| 4 # you may not use this file except in compliance with the License. | |
| 5 # You may obtain a copy of the License at | |
| 6 # | |
| 7 # http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 # | |
| 9 # Unless required by applicable law or agreed to in writing, software | |
| 10 # distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 # See the License for the specific language governing permissions and | |
| 13 # limitations under the License. | |
| 14 | 4 |
| 15 """Generic utils.""" | 5 """Generic utils.""" |
| 16 | 6 |
| 17 import errno | 7 import errno |
| 18 import logging | 8 import logging |
| 19 import os | 9 import os |
| 20 import Queue | 10 import Queue |
| 21 import re | 11 import re |
| 22 import stat | 12 import stat |
| 23 import subprocess | 13 import subprocess |
| 24 import sys | 14 import sys |
| 25 import threading | 15 import threading |
| 26 import time | 16 import time |
| 27 import xml.dom.minidom | 17 import xml.dom.minidom |
| 28 import xml.parsers.expat | 18 import xml.parsers.expat |
| 29 | 19 |
| 30 | 20 |
| 21 def hack_subprocess(): |
| 22 """subprocess functions may throw exceptions when used in multiple threads. |
| 23 |
| 24 See http://bugs.python.org/issue1731717 for more information. |
| 25 """ |
| 26 subprocess._cleanup = lambda: None |
| 27 |
| 28 |
| 31 class Error(Exception): | 29 class Error(Exception): |
| 32 """gclient exception class.""" | 30 """gclient exception class.""" |
| 33 pass | 31 pass |
| 34 | 32 |
| 35 | 33 |
| 36 class CheckCallError(OSError, Error): | 34 class CheckCallError(OSError, Error): |
| 37 """CheckCall() returned non-0.""" | 35 """CheckCall() returned non-0.""" |
| 38 def __init__(self, command, cwd, returncode, stdout, stderr=None): | 36 def __init__(self, command, cwd, returncode, stdout, stderr=None): |
| 39 OSError.__init__(self, command, cwd, returncode, stdout, stderr) | 37 OSError.__init__(self, command, cwd, returncode, stdout, stderr) |
| 40 Error.__init__(self, command) | 38 Error.__init__(self, command) |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 | 564 |
| 567 In gclient's case, Dependencies sometime needs to be run out of order due to | 565 In gclient's case, Dependencies sometime needs to be run out of order due to |
| 568 From() keyword. This class manages that all the required dependencies are run | 566 From() keyword. This class manages that all the required dependencies are run |
| 569 before running each one. | 567 before running each one. |
| 570 | 568 |
| 571 Methods of this class are thread safe. | 569 Methods of this class are thread safe. |
| 572 """ | 570 """ |
| 573 def __init__(self, jobs, progress): | 571 def __init__(self, jobs, progress): |
| 574 """jobs specifies the number of concurrent tasks to allow. progress is a | 572 """jobs specifies the number of concurrent tasks to allow. progress is a |
| 575 Progress instance.""" | 573 Progress instance.""" |
| 574 hack_subprocess() |
| 576 # Set when a thread is done or a new item is enqueued. | 575 # Set when a thread is done or a new item is enqueued. |
| 577 self.ready_cond = threading.Condition() | 576 self.ready_cond = threading.Condition() |
| 578 # Maximum number of concurrent tasks. | 577 # Maximum number of concurrent tasks. |
| 579 self.jobs = jobs | 578 self.jobs = jobs |
| 580 # List of WorkItem, for gclient, these are Dependency instances. | 579 # List of WorkItem, for gclient, these are Dependency instances. |
| 581 self.queued = [] | 580 self.queued = [] |
| 582 # List of strings representing each Dependency.name that was run. | 581 # List of strings representing each Dependency.name that was run. |
| 583 self.ran = [] | 582 self.ran = [] |
| 584 # List of items currently running. | 583 # List of items currently running. |
| 585 self.running = [] | 584 self.running = [] |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 logging.info('Caught exception in thread %s' % self.item.name) | 710 logging.info('Caught exception in thread %s' % self.item.name) |
| 712 logging.info(str(sys.exc_info())) | 711 logging.info(str(sys.exc_info())) |
| 713 work_queue.exceptions.put(sys.exc_info()) | 712 work_queue.exceptions.put(sys.exc_info()) |
| 714 logging.info('Task %s done' % self.item.name) | 713 logging.info('Task %s done' % self.item.name) |
| 715 | 714 |
| 716 work_queue.ready_cond.acquire() | 715 work_queue.ready_cond.acquire() |
| 717 try: | 716 try: |
| 718 work_queue.ready_cond.notifyAll() | 717 work_queue.ready_cond.notifyAll() |
| 719 finally: | 718 finally: |
| 720 work_queue.ready_cond.release() | 719 work_queue.ready_cond.release() |
| OLD | NEW |