summaryrefslogtreecommitdiffstats
path: root/src/software
diff options
context:
space:
mode:
authorMichal Minar <miminar@redhat.com>2014-01-02 13:12:16 +0100
committerMichal Minar <miminar@redhat.com>2014-01-06 13:40:42 +0100
commit260b1ad4cb54cd953785dab7eb33d62b5b1b21c9 (patch)
treeabd46d76665923a1418a77bc807059a2e0dbbb9b /src/software
parent41f4ea0290be9393cd0a5560c47e1c22b1fd1800 (diff)
downloadopenlmi-providers-260b1ad4cb54cd953785dab7eb33d62b5b1b21c9.tar.gz
openlmi-providers-260b1ad4cb54cd953785dab7eb33d62b5b1b21c9.tar.xz
openlmi-providers-260b1ad4cb54cd953785dab7eb33d62b5b1b21c9.zip
software: fixed possible deadlock in session manager
* peak() method used to lock wrong mutex, which could cause a deadlock. * pop_reply() method could block if non-blocking access had been requested.
Diffstat (limited to 'src/software')
-rw-r--r--src/software/lmi/software/yumdb/sessionmanager.py30
1 files changed, 20 insertions, 10 deletions
diff --git a/src/software/lmi/software/yumdb/sessionmanager.py b/src/software/lmi/software/yumdb/sessionmanager.py
index 8bc0474..07450ac 100644
--- a/src/software/lmi/software/yumdb/sessionmanager.py
+++ b/src/software/lmi/software/yumdb/sessionmanager.py
@@ -208,7 +208,7 @@ class SessionManager(threading.Thread):
:rtype: tuple
"""
- with self._busy_lock:
+ with self._reply_cond:
return self._reply
@property
@@ -223,7 +223,7 @@ class SessionManager(threading.Thread):
@property
def is_busy(self):
"""
- :returns: Whether there is job being processed.
+ :returns: Whether there is a job being processed.
:type: boolean
"""
if self._busy_lock.acquire(False):
@@ -243,14 +243,24 @@ class SessionManager(threading.Thread):
:returns: Received reply in form ``(jobid, result_code, result_data)``.
:rtype: tuple
"""
- with self._busy_lock:
- reply = self._reply
- if reply is None and no_wait:
- raise TQueue.Empty("reply has been not received yet")
- while reply is None:
- self._busy_cond.wait()
- reply = self._reply
- self._reply = None
+ reply = None
+ if self._busy_lock.acquire(not no_wait):
+ try:
+ with self._reply_cond:
+ reply = self._reply
+ self._reply = None
+ if not no_wait:
+ while reply is None:
+ self._busy_cond.wait()
+ with self._reply_cond:
+ reply = self._reply
+ self._reply = None
+ finally:
+ self._busy_lock.release()
+
+ if reply is None: # this is possible only if no_wait=True
+ raise TQueue.Empty("reply has not been received yet")
+
return reply
@cmpi_logging.trace_method