Initial step into making Dependency thread safe
R=dpranke@chromium.org
BUG=
TEST=
Review URL: http://codereview.chromium.org/7892034
git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@101135 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gclient_utils.py b/gclient_utils.py
index 89050b7..2402519 100644
--- a/gclient_utils.py
+++ b/gclient_utils.py
@@ -456,19 +456,45 @@
return config_dir, env['entries']
+def lockedmethod(method):
+ """Method decorator that holds self.lock for the duration of the call."""
+ def inner(self, *args, **kwargs):
+ try:
+ try:
+ self.lock.acquire()
+ except KeyboardInterrupt:
+ print >> sys.stderr, 'Was deadlocked'
+ raise
+ return method(self, *args, **kwargs)
+ finally:
+ self.lock.release()
+ return inner
+
+
class WorkItem(object):
"""One work item."""
- def __init__(self):
+ def __init__(self, name):
# A list of string, each being a WorkItem name.
- self.requirements = []
+ self._requirements = set()
# A unique string representing this work item.
- self.name = None
+ self._name = name
+ self.lock = threading.RLock()
+ @lockedmethod
def run(self, work_queue):
"""work_queue is passed as keyword argument so it should be
the last parameters of the function when you override it."""
pass
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ @lockedmethod
+ def requirements(self):
+ return tuple(self._requirements)
+
class ExecutionQueue(object):
"""Runs a set of WorkItem that have interdependencies and were WorkItem are