From: Ben Darnell Date: Tue, 25 Oct 2011 05:02:15 +0000 (-0700) Subject: Fix zero-byte writes in IOStream. X-Git-Tag: v2.2.0~86 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf7557191bc92d6b5c31212e012d2f64e818382d;p=thirdparty%2Ftornado.git Fix zero-byte writes in IOStream. Previously zero-byte writes would cause the CPU to run at 100% and would never call their callback (if any). --- diff --git a/tornado/iostream.py b/tornado/iostream.py index 653652753..6b02b19ae 100644 --- a/tornado/iostream.py +++ b/tornado/iostream.py @@ -211,7 +211,10 @@ class IOStream(object): """ assert isinstance(data, bytes_type) self._check_closed() - self._write_buffer.append(data) + if data: + # We use bool(_write_buffer) as a proxy for write_buffer_size>0, + # so never put empty strings in the buffer. + self._write_buffer.append(data) self._write_callback = stack_context.wrap(callback) self._handle_write() if self._write_buffer: diff --git a/tornado/test/iostream_test.py b/tornado/test/iostream_test.py index f35614da9..43b2e17bc 100644 --- a/tornado/test/iostream_test.py +++ b/tornado/test/iostream_test.py @@ -1,4 +1,5 @@ from tornado import netutil +from tornado.ioloop import IOLoop from tornado.iostream import IOStream from tornado.testing import AsyncHTTPTestCase, LogTrapTestCase, get_unused_port from tornado.util import b @@ -57,6 +58,16 @@ class TestIOStream(AsyncHTTPTestCase, LogTrapTestCase): data = self.wait() self.assertEqual(data, b("200")) + def test_write_zero_bytes(self): + # Attempting to write zero bytes should run the callback without + # going into an infinite loop. + server, client = self.make_iostream_pair() + server.write(b(''), callback=self.stop) + self.wait() + # As a side effect, the stream is now listening for connection + # close (if it wasn't already), but is not listening for writes + self.assertEqual(server._state, IOLoop.READ|IOLoop.ERROR) + def test_connection_refused(self): # When a connection is refused, the connect callback should not # be run. (The kqueue IOLoop used to behave differently from the