]> granicus.if.org Git - python/commitdiff
Backport of r64767 from trunk
authorGregory P. Smith <greg@mad-scientist.com>
Sun, 17 Aug 2008 23:06:19 +0000 (23:06 +0000)
committerGregory P. Smith <greg@mad-scientist.com>
Sun, 17 Aug 2008 23:06:19 +0000 (23:06 +0000)
Fixes Issue #3309: Fix bz2.BZFile iterator to release its internal lock
properly when raising an exception due to the bz2file being closed.
Prevents a deadlock.

Lib/test/test_bz2.py
Misc/NEWS
Modules/bz2module.c

index 709850d2298eae185f11c775716af7ea0a4a0755..554fe868af70c0863db6019a5d75aad57e05e1a4 100644 (file)
@@ -110,6 +110,17 @@ class BZ2FileTest(BaseTest):
         self.assertEqual(list(iter(bz2f)), sio.readlines())
         bz2f.close()
 
+    def testClosedIteratorDeadlock(self):
+        # "Test that iteration on a closed bz2file releases the lock."
+        # http://bugs.python.org/issue3309
+        self.createTempFile()
+        bz2f = BZ2File(self.filename)
+        bz2f.close()
+        self.assertRaises(ValueError, bz2f.next)
+        # This call will deadlock of the above .next call failed to
+        # release the lock.
+        self.assertRaises(ValueError, bz2f.readlines)
+
     def testXReadLines(self):
         # "Test BZ2File.xreadlines()"
         self.createTempFile()
index 8864aa9849b9c28d26706da99a5c4d63fb48e19d..23c2384eb6790d72a33732569eb071daed47c4c7 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -148,6 +148,10 @@ Library
   up in the child process to prevent deadlock and report proper thread counts
   if the new process uses the threading module.
 
+- Issue #3309: Fix bz2.BZFile iterator to release its internal lock
+  properly when raising an exception due to the bz2file being closed.
+  Prevents a deadlock.
+
 
 Extension Modules
 -----------------
index 9e868c5eb692b86e80fab9979771c4a6cf60a588..73de628e860009128210c562e0a950c52784507a 100644 (file)
@@ -1437,6 +1437,7 @@ BZ2File_iternext(BZ2FileObject *self)
        PyStringObject* ret;
        ACQUIRE_LOCK(self);
        if (self->mode == MODE_CLOSED) {
+                RELEASE_LOCK(self);
                PyErr_SetString(PyExc_ValueError,
                                "I/O operation on closed file");
                return NULL;