Add resource locking in gclient
There are entries in the DEPS file where two folders uses the same
git URL (ie. freetype2). This doesn't work well with git caches because
each task will run on it's own and might try to clobber on top of each other.
This adds another field in a WorkItem which is a list of resources. When the
work queue is flushed, it has to make sure that none of a newly added workitem
has any resource conflicts.
BUG=618124
Review-Url: https://codereview.chromium.org/2049583003
diff --git a/gclient_utils.py b/gclient_utils.py
index 9d1b9df..76cbe2d 100644
--- a/gclient_utils.py
+++ b/gclient_utils.py
@@ -784,6 +784,7 @@
self._name = name
self.outbuf = cStringIO.StringIO()
self.start = self.finish = None
+ self.resources = [] # List of resources this work item requires.
def run(self, work_queue):
"""work_queue is passed as keyword argument so it should be
@@ -869,6 +870,15 @@
----------------------------------------""" % (
task.name, comment, elapsed, task.outbuf.getvalue().strip())
+ def _is_conflict(self, job):
+ """Checks to see if a job will conflict with another running job."""
+ for running_job in self.running:
+ for used_resource in running_job.item.resources:
+ logging.debug('Checking resource %s' % used_resource)
+ if used_resource in job.resources:
+ return True
+ return False
+
def flush(self, *args, **kwargs):
"""Runs all enqueued items until all are executed."""
kwargs['work_queue'] = self
@@ -892,9 +902,10 @@
# Verify its requirements.
if (self.ignore_requirements or
not (set(self.queued[i].requirements) - set(self.ran))):
- # Start one work item: all its requirements are satisfied.
- self._run_one_task(self.queued.pop(i), args, kwargs)
- break
+ if not self._is_conflict(self.queued[i]):
+ # Start one work item: all its requirements are satisfied.
+ self._run_one_task(self.queued.pop(i), args, kwargs)
+ break
else:
# Couldn't find an item that could run. Break out the outher loop.
break