From: Ben Dyer Date: Fri, 12 Jul 2013 06:35:09 +0000 (+1000) Subject: Correctly handle EAGAIN when writing to PipeIOStreams X-Git-Tag: v3.2.0b1~105^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11236e77c20d883b363aebea3d6341d296ed94ce;p=thirdparty%2Ftornado.git Correctly handle EAGAIN when writing to PipeIOStreams BaseIOStream._handle_write needs to catch IOError and OSError as well as socket.error in order to handle EAGAIN when writing to a PipeIOStream (which doesn't appear to raise socket.error when the buffer is full). This also provides consistency with the exceptions caught by BaseIOStream._read_to_buffer. --- diff --git a/tornado/iostream.py b/tornado/iostream.py index 6a507a81d..cd97f9d30 100644 --- a/tornado/iostream.py +++ b/tornado/iostream.py @@ -562,7 +562,7 @@ class BaseIOStream(object): self._write_buffer_frozen = False _merge_prefix(self._write_buffer, num_bytes) self._write_buffer.popleft() - except socket.error as e: + except (socket.error, IOError, OSError) as e: if e.args[0] in _ERRNO_WOULDBLOCK: self._write_buffer_frozen = True break diff --git a/tornado/test/iostream_test.py b/tornado/test/iostream_test.py index 0650c1104..24f8eef4c 100644 --- a/tornado/test/iostream_test.py +++ b/tornado/test/iostream_test.py @@ -543,3 +543,21 @@ class TestPipeIOStream(AsyncTestCase): self.assertEqual(data, b"ld") rs.close() + + def test_pipe_iostream_big_write(self): + r, w = os.pipe() + + rs = PipeIOStream(r, io_loop=self.io_loop) + ws = PipeIOStream(w, io_loop=self.io_loop) + + NUM_BYTES = 1048576 + + # Write 1MB of data, which should fill the buffer + ws.write(b"1" * NUM_BYTES) + + rs.read_bytes(NUM_BYTES, self.stop) + data = self.wait() + self.assertEqual(data, b"1" * NUM_BYTES) + + ws.close() + rs.close()