OLD | NEW |
1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2011 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 errno | 7 import errno |
8 import logging | 8 import logging |
9 import os | 9 import os |
10 import Queue | 10 import Queue |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 if not config_path: | 449 if not config_path: |
450 print "Can't find %s" % config_file | 450 print "Can't find %s" % config_file |
451 return None | 451 return None |
452 | 452 |
453 env = {} | 453 env = {} |
454 execfile(config_path, env) | 454 execfile(config_path, env) |
455 config_dir = os.path.dirname(config_path) | 455 config_dir = os.path.dirname(config_path) |
456 return config_dir, env['entries'] | 456 return config_dir, env['entries'] |
457 | 457 |
458 | 458 |
| 459 def lockedmethod(method): |
| 460 """Method decorator that holds self.lock for the duration of the call.""" |
| 461 def inner(self, *args, **kwargs): |
| 462 try: |
| 463 try: |
| 464 self.lock.acquire() |
| 465 except KeyboardInterrupt: |
| 466 print >> sys.stderr, 'Was deadlocked' |
| 467 raise |
| 468 return method(self, *args, **kwargs) |
| 469 finally: |
| 470 self.lock.release() |
| 471 return inner |
| 472 |
| 473 |
459 class WorkItem(object): | 474 class WorkItem(object): |
460 """One work item.""" | 475 """One work item.""" |
461 def __init__(self): | 476 def __init__(self, name): |
462 # A list of string, each being a WorkItem name. | 477 # A list of string, each being a WorkItem name. |
463 self.requirements = [] | 478 self._requirements = set() |
464 # A unique string representing this work item. | 479 # A unique string representing this work item. |
465 self.name = None | 480 self._name = name |
| 481 self.lock = threading.RLock() |
466 | 482 |
| 483 @lockedmethod |
467 def run(self, work_queue): | 484 def run(self, work_queue): |
468 """work_queue is passed as keyword argument so it should be | 485 """work_queue is passed as keyword argument so it should be |
469 the last parameters of the function when you override it.""" | 486 the last parameters of the function when you override it.""" |
470 pass | 487 pass |
471 | 488 |
| 489 @property |
| 490 def name(self): |
| 491 return self._name |
| 492 |
| 493 @property |
| 494 @lockedmethod |
| 495 def requirements(self): |
| 496 return tuple(self._requirements) |
| 497 |
472 | 498 |
473 class ExecutionQueue(object): | 499 class ExecutionQueue(object): |
474 """Runs a set of WorkItem that have interdependencies and were WorkItem are | 500 """Runs a set of WorkItem that have interdependencies and were WorkItem are |
475 added as they are processed. | 501 added as they are processed. |
476 | 502 |
477 In gclient's case, Dependencies sometime needs to be run out of order due to | 503 In gclient's case, Dependencies sometime needs to be run out of order due to |
478 From() keyword. This class manages that all the required dependencies are run | 504 From() keyword. This class manages that all the required dependencies are run |
479 before running each one. | 505 before running each one. |
480 | 506 |
481 Methods of this class are thread safe. | 507 Methods of this class are thread safe. |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 logging.info('Caught exception in thread %s' % self.item.name) | 661 logging.info('Caught exception in thread %s' % self.item.name) |
636 logging.info(str(sys.exc_info())) | 662 logging.info(str(sys.exc_info())) |
637 work_queue.exceptions.put(sys.exc_info()) | 663 work_queue.exceptions.put(sys.exc_info()) |
638 logging.info('Task %s done' % self.item.name) | 664 logging.info('Task %s done' % self.item.name) |
639 | 665 |
640 work_queue.ready_cond.acquire() | 666 work_queue.ready_cond.acquire() |
641 try: | 667 try: |
642 work_queue.ready_cond.notifyAll() | 668 work_queue.ready_cond.notifyAll() |
643 finally: | 669 finally: |
644 work_queue.ready_cond.release() | 670 work_queue.ready_cond.release() |
OLD | NEW |