From 11236e77c20d883b363aebea3d6341d296ed94ce Mon Sep 17 00:00:00 2001 From: Ben Dyer Date: Fri, 12 Jul 2013 16:35:09 +1000 Subject: [PATCH] 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. --- tornado/iostream.py | 2 +- tornado/test/iostream_test.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) 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() -- 2.47.2