summaryrefslogtreecommitdiff
path: root/gear/__init__.py
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-02-27 15:52:39 +0000
committerGerrit Code Review <review@openstack.org>2015-02-27 15:52:39 +0000
commit865be4cec8009207e57c67f80a5b2b9ee4015fd6 (patch)
tree641217f450a676a751fda9d681ff5a79379013c0 /gear/__init__.py
parenta6d28b456ff69acd481d38d169ee327eea520700 (diff)
parent77ba48998f1f1dd881bff852b7c07ef87998e359 (diff)
downloadgear-865be4cec8009207e57c67f80a5b2b9ee4015fd6.tar.gz
Merge "Fix race between stopWaitingForJobs() and getJob()"
Diffstat (limited to 'gear/__init__.py')
-rw-r--r--gear/__init__.py19
1 files changed, 18 insertions, 1 deletions
diff --git a/gear/__init__.py b/gear/__init__.py
index 20c8974..0345a35 100644
--- a/gear/__init__.py
+++ b/gear/__init__.py
@@ -1856,6 +1856,14 @@ class Worker(BaseClient):
if not job:
self._updateStateMachines()
+
+ # That variable get cleared during _shutdown(), before the
+ # stopWaitingForJobs() is called. The check has to happen with the
+ # self.job_lock held, otherwise there would be a window for race
+ # conditions between manipulation of "running" and
+ # "waiting_for_jobs".
+ if not self.running:
+ raise InterruptedError()
finally:
self.job_lock.release()
@@ -1902,7 +1910,16 @@ class Worker(BaseClient):
self.job_lock.release()
def _shutdown(self):
- super(Worker, self)._shutdown()
+ self.job_lock.acquire()
+ try:
+ # The upstream _shutdown() will clear the "running" bool. Because
+ # that is a variable which is used for proper synchronization of
+ # the exit within getJob() which might be about to be called from a
+ # separate thread, it's important to call it with a proper lock
+ # being held.
+ super(Worker, self)._shutdown()
+ finally:
+ self.job_lock.release()
self.stopWaitingForJobs()
def handleNoop(self, packet):