/** * Tests wait() and notify() when buffer is empty. */ public function testInputWhenBufferIsEmpty() { // Initializes a piped input stream. $input = new PipedInputStream(); // Initializes a consumer that reads 1 byte. $consumer = new Consumer($input, 1); // When started, it will wait because the buffer is empty. $consumer->start(); $this->assertEquals(0, $input->available()); // Adds contents to the buffer and notify the thread. $input->synchronized(function () { $buffer = $this->buffer; $buffer[] = '*'; $buffer[] = '*'; $this->notify(); }); // Waits till the thread has finished its job. $consumer->join(); $this->assertEquals(1, $input->available()); // Asserts the thread is not waiting. $this->assertFalse($input->isRunning()); }
/** * Writes data to a piped output stream, when the buffer of its downstream * is full. * * The producer thread is blocked first. This can be confirmed by checking * the 'waiting' status of the downstream object. * * To wake up the producer thread, a byte is shifted out of the buffer and * the downstream is notified. * * Finally, check the 'waiting' status again to confirm the producer thread * has completed its job. */ public function testOutputWhenBufferIsFull() { // Initializes a piped input stream. $downstream = new PipedInputStream(); // Initializes buffer and fills it up with '*'. $buffer = $downstream->buffer; for ($i = 0; $i < PipedInputStream::BUFFER_SIZE; $i++) { $buffer[] = '*'; } $data = '*'; // Initializes a piped output stream. $output = new PipedOutputStream($downstream); // Initializes a producer. $producer = new Producer($output, $data); // Starts the producer. Because buffer is full, the thread will wait. $producer->start(); // Shifts one byte off the buffer and notify the thread. $downstream->synchronized(function () { $buffer = $this->buffer; $buffer->shift(); $this->notify(); }); // Waits for the thread to finish its job. $producer->join(); $this->assertTrue(true); // Now asserts the thread is not waiting. $this->assertFalse($downstream->isRunning()); }