Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: gclient_utils.py

Issue 7892034: Initial step into making Dependency thread safe (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gclient.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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()
Dirk Pranke 2011/09/14 20:00:39 Why RLock instead of Lock()?
M-A Ruel 2011/09/14 20:03:03 I'll need a RLock due to some locking recursion wh
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):
Dirk Pranke 2011/09/14 20:00:39 Do you really need a lock here? Isn't this guarant
M-A Ruel 2011/09/14 20:03:03 More or less but I want to reduce the GIL assumpti
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
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()
OLDNEW
« no previous file with comments | « gclient.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698