/** * @param resource $socket * @param bool $autoClose True to close the resource on destruct, false to leave it open. */ public function __construct($socket, bool $autoClose = true) { parent::__construct($socket, $autoClose); $this->queue = new \SplQueue(); $this->poll = $this->createPoll($socket, $this->queue); $this->onCancelled = function () { $this->poll->cancel(); $this->queue->shift(); }; try { list($this->address, $this->port) = Socket\getName($socket, false); } catch (FailureException $exception) { $this->close(); } }
/** * @coroutine * * @param callable $function Function name to execute. * @param mixed ...$args Arguments to pass to function. * * @return \Generator * * @resolve resource * * @throws \Icicle\Postgres\Exception\FailureException */ private function send(callable $function, ...$args) : \Generator { while (null !== $this->delayed) { try { (yield $this->delayed); } catch (\Throwable $exception) { // Ignore failure from another operation. } } $result = $function($this->handle, ...$args); if (false === $result) { throw new FailureException(\pg_last_error($this->handle)); } $this->delayed = new Delayed($this->onCancelled); $this->poll->setData($this->delayed); $this->await->setData($this->delayed); $this->poll->listen(); if (0 === $result) { $this->await->listen(); } try { $result = (yield $this->delayed); } finally { $this->delayed = null; $this->poll->cancel(); $this->await->cancel(); } return $result; }
/** * @param resource $socket * @param bool $autoClose True to close the resource on destruct, false to leave it open. */ public function __construct($socket, bool $autoClose = true) { parent::__construct($socket, $autoClose); stream_set_read_buffer($socket, 0); stream_set_write_buffer($socket, 0); stream_set_chunk_size($socket, self::MAX_PACKET_SIZE); $this->readQueue = new \SplQueue(); $this->writeQueue = new \SplQueue(); $this->poll = $this->createPoll($socket, $this->readQueue); $this->await = $this->createAwait($socket, $this->writeQueue); $this->onReceiveCancelled = function () { $this->poll->cancel(); $this->readQueue->shift(); }; $this->onSendCancelled = function (\Exception $exception) { $this->free($exception); }; try { list($this->address, $this->port) = Socket\getName($socket, false); } catch (FailureException $exception) { $this->close(); } }
/** * Shifts the given data back to the front of the stream and will be the first bytes returned from any pending or * subsequent read. * * @param string $data */ public function unshift(string $data) { $data = (string) $data; if (!strlen($data)) { return; } $this->buffer = $data . $this->buffer; if (!$this->queue->isEmpty()) { /** @var \Icicle\Awaitable\Delayed $delayed */ $delayed = $this->queue->shift(); $delayed->resolve(); $this->poll->cancel(); } }
public function done() { if (0 === --$this->requests) { $this->poll->cancel(); } }