[2.7] bpo-31530: Stop crashes when iterating over a file on multiple threads. (#3672)

diff --git a/Lib/test/test_file2k.py b/Lib/test/test_file2k.py
index e39ef70..d8966e0 100644
--- a/Lib/test/test_file2k.py
+++ b/Lib/test/test_file2k.py
@@ -652,6 +652,38 @@
             self.f.writelines('')
         self._test_close_open_io(io_func)
 
+    def test_iteration_torture(self):
+        # bpo-31530: Crash when concurrently iterate over a file.
+        with open(self.filename, "wb") as fp:
+            for i in xrange(2**20):
+                fp.write(b"0"*50 + b"\n")
+        with open(self.filename, "rb") as f:
+            def iterate():
+                try:
+                    for l in f:
+                        pass
+                except IOError:
+                    pass
+            self._run_workers(iterate, 10)
+
+    def test_iteration_seek(self):
+        # bpo-31530: Crash when concurrently seek and iterate over a file.
+        with open(self.filename, "wb") as fp:
+            for i in xrange(10000):
+                fp.write(b"0"*50 + b"\n")
+        with open(self.filename, "rb") as f:
+            it = iter([1] + [0]*10)  # one thread reads, others seek
+            def iterate():
+                try:
+                    if next(it):
+                        for l in f:
+                            pass
+                    else:
+                        for i in range(100):
+                            f.seek(i*100, 0)
+                except IOError:
+                    pass
+            self._run_workers(iterate, 10)
 
 @unittest.skipUnless(os.name == 'posix', 'test requires a posix system.')
 class TestFileSignalEINTR(unittest.TestCase):