Skip to content

Commit 5d89f2a

Browse files
committed
Merge pull request #22 from arnaud-lb/write-in-drain
Fixed double-writes when write() is called during 'drain' event
2 parents 9ddb6af + 548ba15 commit 5d89f2a

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/Buffer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,12 @@ public function handleWrite()
111111
}
112112

113113
$len = strlen($this->data);
114+
$this->data = (string) substr($this->data, $sent);
115+
114116
if ($len >= $this->softLimit && $len - $sent < $this->softLimit) {
115117
$this->emit('drain', array($this));
116118
}
117119

118-
$this->data = (string) substr($this->data, $sent);
119-
120120
if (0 === strlen($this->data)) {
121121
$this->loop->removeWriteStream($this->stream);
122122
$this->listening = false;

tests/BufferTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,36 @@ public function testDrain()
9494
$buffer->write("bar\n");
9595
}
9696

97+
/**
98+
* @covers React\Stream\Buffer::write
99+
* @covers React\Stream\Buffer::handleWrite
100+
*/
101+
public function testWriteInDrain()
102+
{
103+
$writeStreams = array();
104+
105+
$stream = fopen('php://temp', 'r+');
106+
$loop = $this->createWriteableLoopMock();
107+
$loop->preventWrites = true;
108+
109+
$buffer = new Buffer($stream, $loop);
110+
$buffer->softLimit = 2;
111+
$buffer->on('error', $this->expectCallableNever());
112+
113+
$buffer->once('drain', function ($buffer) {
114+
$buffer->listening = false;
115+
$buffer->write("bar\n");
116+
});
117+
118+
$this->assertFalse($buffer->write("foo"));
119+
$loop->preventWrites = false;
120+
$buffer->listening = false;
121+
$buffer->write("\n");
122+
123+
fseek($stream, 0);
124+
$this->assertSame("foo\nbar\n", stream_get_contents($stream));
125+
}
126+
97127
/**
98128
* @covers React\Stream\Buffer::end
99129
*/

0 commit comments

Comments
 (0)