From 548ba15031ef7c073f236147d93dcc6125ceaa37 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Thu, 11 Jun 2015 16:04:14 +0200 Subject: [PATCH] Fixed double-writes when write() is called during 'drain' event --- src/Buffer.php | 4 ++-- tests/BufferTest.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Buffer.php b/src/Buffer.php index 18211ea..e7626c6 100644 --- a/src/Buffer.php +++ b/src/Buffer.php @@ -111,12 +111,12 @@ public function handleWrite() } $len = strlen($this->data); + $this->data = (string) substr($this->data, $sent); + if ($len >= $this->softLimit && $len - $sent < $this->softLimit) { $this->emit('drain', [$this]); } - $this->data = (string) substr($this->data, $sent); - if (0 === strlen($this->data)) { $this->loop->removeWriteStream($this->stream); $this->listening = false; diff --git a/tests/BufferTest.php b/tests/BufferTest.php index 1fc4d1e..431c23f 100644 --- a/tests/BufferTest.php +++ b/tests/BufferTest.php @@ -94,6 +94,36 @@ public function testDrain() $buffer->write("bar\n"); } + /** + * @covers React\Stream\Buffer::write + * @covers React\Stream\Buffer::handleWrite + */ + public function testWriteInDrain() + { + $writeStreams = array(); + + $stream = fopen('php://temp', 'r+'); + $loop = $this->createWriteableLoopMock(); + $loop->preventWrites = true; + + $buffer = new Buffer($stream, $loop); + $buffer->softLimit = 2; + $buffer->on('error', $this->expectCallableNever()); + + $buffer->once('drain', function ($buffer) { + $buffer->listening = false; + $buffer->write("bar\n"); + }); + + $this->assertFalse($buffer->write("foo")); + $loop->preventWrites = false; + $buffer->listening = false; + $buffer->write("\n"); + + fseek($stream, 0); + $this->assertSame("foo\nbar\n", stream_get_contents($stream)); + } + /** * @covers React\Stream\Buffer::end */