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 |