diff options
author | Jenkins <jenkins@review.openstack.org> | 2015-02-27 15:52:39 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2015-02-27 15:52:39 +0000 |
commit | 865be4cec8009207e57c67f80a5b2b9ee4015fd6 (patch) | |
tree | 641217f450a676a751fda9d681ff5a79379013c0 /gear | |
parent | a6d28b456ff69acd481d38d169ee327eea520700 (diff) | |
parent | 77ba48998f1f1dd881bff852b7c07ef87998e359 (diff) | |
download | gear-865be4cec8009207e57c67f80a5b2b9ee4015fd6.tar.gz |
Merge "Fix race between stopWaitingForJobs() and getJob()"
Diffstat (limited to 'gear')
-rw-r--r-- | gear/__init__.py | 19 |
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): |