[Python-checkins] python/dist/src/Lib Queue.py,1.14,1.15
mhammond@sourceforge.net
mhammond@sourceforge.net
Thu, 18 Apr 2002 17:11:37 -0700
Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv3478
Modified Files:
Queue.py
Log Message:
Fix bug 544473 - "Queue module can deadlock".
Use try/finally to ensure all Queue locks remain stable.
Includes test case. Bugfix candidate.
Index: Queue.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/Queue.py,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** Queue.py 18 Feb 2001 03:30:53 -0000 1.14
--- Queue.py 19 Apr 2002 00:11:31 -0000 1.15
***************
*** 56,66 ****
raise Full
self.mutex.acquire()
! was_empty = self._empty()
! self._put(item)
! if was_empty:
! self.esema.release()
! if not self._full():
! self.fsema.release()
! self.mutex.release()
def put_nowait(self, item):
--- 56,77 ----
raise Full
self.mutex.acquire()
! release_fsema = True
! try:
! was_empty = self._empty()
! self._put(item)
! # If we fail before here, the empty state has
! # not changed, so we can skip the release of esema
! if was_empty:
! self.esema.release()
! # If we fail before here, the queue can not be full, so
! # release_full_sema remains True
! release_fsema = not self._full()
! finally:
! # Catching system level exceptions here (RecursionDepth,
! # OutOfMemory, etc) - so do as little as possible in terms
! # of Python calls.
! if release_fsema:
! self.fsema.release()
! self.mutex.release()
def put_nowait(self, item):
***************
*** 85,95 ****
raise Empty
self.mutex.acquire()
! was_full = self._full()
! item = self._get()
! if was_full:
! self.fsema.release()
! if not self._empty():
! self.esema.release()
! self.mutex.release()
return item
--- 96,114 ----
raise Empty
self.mutex.acquire()
! release_esema = True
! try:
! was_full = self._full()
! item = self._get()
! # If we fail before here, the full state has
! # not changed, so we can skip the release of fsema
! if was_full:
! self.fsema.release()
! # Failure means empty state also unchanged - release_esema
! # remains True.
! release_esema = not self._empty()
! finally:
! if release_esema:
! self.esema.release()
! self.mutex.release()
return item