Skip to content

Commit 12859f7

Browse files
authored
Merge pull request #61 from clue-labs/buffer-close
Consistent close behavior for Buffer
2 parents d2d25e1 + d475b9e commit 12859f7

2 files changed

Lines changed: 73 additions & 1 deletion

File tree

src/Buffer.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Buffer extends EventEmitter implements WritableStreamInterface
1212
public $listening = false;
1313
public $softLimit = 65536;
1414
private $writable = true;
15+
private $closed = false;
1516
private $loop;
1617
private $data = '';
1718

@@ -64,11 +65,21 @@ public function end($data = null)
6465

6566
public function close()
6667
{
68+
if ($this->closed) {
69+
return;
70+
}
71+
72+
if ($this->listening) {
73+
$this->listening = false;
74+
$this->loop->removeWriteStream($this->stream);
75+
}
76+
77+
$this->closed = true;
6778
$this->writable = false;
68-
$this->listening = false;
6979
$this->data = '';
7080

7181
$this->emit('close', array($this));
82+
$this->removeAllListeners();
7283
}
7384

7485
public function handleWrite()
@@ -108,6 +119,7 @@ public function handleWrite()
108119
}
109120

110121
$this->emit('error', array(new \RuntimeException('Unable to write to stream: ' . $error->getMessage(), 0, $error), $this));
122+
$this->close();
111123

112124
return;
113125
}

tests/BufferTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,20 @@ public function testEmptyWriteDoesNotAddToLoop()
7777
$buffer->write(null);
7878
}
7979

80+
/**
81+
* @covers React\Stream\Buffer::write
82+
*/
83+
public function testWriteWillAddStreamToLoop()
84+
{
85+
$stream = fopen('php://temp', 'r+');
86+
$loop = $this->createLoopMock();
87+
$buffer = new Buffer($stream, $loop);
88+
89+
$loop->expects($this->once())->method('addWriteStream')->with($stream);
90+
91+
$buffer->write('foo');
92+
}
93+
8094
/**
8195
* @covers React\Stream\Buffer::write
8296
* @covers React\Stream\Buffer::handleWrite
@@ -292,6 +306,52 @@ public function testClose()
292306
$this->assertTrue($buffer->isWritable());
293307
$buffer->close();
294308
$this->assertFalse($buffer->isWritable());
309+
310+
$this->assertEquals(array(), $buffer->listeners('close'));
311+
}
312+
313+
/**
314+
* @covers React\Stream\Buffer::close
315+
*/
316+
public function testClosingAfterWriteRemovesStreamFromLoop()
317+
{
318+
$stream = fopen('php://temp', 'r+');
319+
$loop = $this->createLoopMock();
320+
$buffer = new Buffer($stream, $loop);
321+
322+
$loop->expects($this->once())->method('removeWriteStream')->with($stream);
323+
324+
$buffer->write('foo');
325+
$buffer->close();
326+
}
327+
328+
/**
329+
* @covers React\Stream\Buffer::close
330+
*/
331+
public function testClosingWithoutWritingDoesNotRemoveStreamFromLoop()
332+
{
333+
$stream = fopen('php://temp', 'r+');
334+
$loop = $this->createLoopMock();
335+
$buffer = new Buffer($stream, $loop);
336+
337+
$loop->expects($this->never())->method('removeWriteStream');
338+
339+
$buffer->close();
340+
}
341+
342+
/**
343+
* @covers React\Stream\Buffer::close
344+
*/
345+
public function testDoubleCloseWillEmitOnlyOnce()
346+
{
347+
$stream = fopen('php://temp', 'r+');
348+
$loop = $this->createLoopMock();
349+
350+
$buffer = new Buffer($stream, $loop);
351+
$buffer->on('close', $this->expectCallableOnce());
352+
353+
$buffer->close();
354+
$buffer->close();
295355
}
296356

297357
/**

0 commit comments

Comments
 (0)