diff --git a/lib/EioHandle.php b/lib/EioHandle.php index 0918ac0..e0bb233 100644 --- a/lib/EioHandle.php +++ b/lib/EioHandle.php @@ -10,16 +10,36 @@ use Amp\Success; use function Amp\call; class EioHandle implements Handle { + /** @var \Amp\File\Internal\EioPoll */ private $poll; + + /** @var resource eio file handle. */ private $fh; + + /** @var string */ private $path; + + /** @var string */ private $mode; + + /** @var int */ private $size; + + /** @var int */ private $position; + + /** @var \SplQueue */ private $queue; + + /** @var bool */ private $isActive = false; + + /** @var bool */ private $writable = true; + /** @var \Amp\Promise|null */ + private $closing; + public function __construct(Internal\EioPoll $poll, $fh, string $path, string $mode, int $size) { $this->poll = $poll; $this->fh = $fh; @@ -169,8 +189,12 @@ class EioHandle implements Handle { * {@inheritdoc} */ public function close(): Promise { + if ($this->closing) { + return $this->closing; + } + $deferred = new Deferred; - $this->poll->listen($deferred->promise()); + $this->poll->listen($this->closing = $deferred->promise()); \eio_close($this->fh, \EIO_PRI_DEFAULT, [$this, "onClose"], $deferred); diff --git a/lib/Internal/FileTask.php b/lib/Internal/FileTask.php index cb9f7a3..4e585e5 100644 --- a/lib/Internal/FileTask.php +++ b/lib/Internal/FileTask.php @@ -112,7 +112,7 @@ class FileTask extends BlockingDriver implements Task { case "fclose": $file->close(); $environment->delete($this->id); - return true; + return; default: throw new \Error('Invalid operation'); diff --git a/lib/ParallelHandle.php b/lib/ParallelHandle.php index 64a06a9..82d3b98 100644 --- a/lib/ParallelHandle.php +++ b/lib/ParallelHandle.php @@ -40,6 +40,9 @@ class ParallelHandle implements Handle { /** @var bool */ private $writable = true; + /** @var \Amp\Promise|null */ + private $closing; + /** * @param \Amp\Parallel\Worker\Worker $worker * @param int $id @@ -73,20 +76,20 @@ class ParallelHandle implements Handle { * {@inheritdoc} */ public function close(): Promise { - if (!$this->writable) { - return new Success; + if ($this->closing) { + return $this->closing; } $this->writable = false; if ($this->worker->isRunning()) { - $promise = $this->worker->enqueue(new Internal\FileTask('fclose', [], $this->id)); + $this->closing = $this->worker->enqueue(new Internal\FileTask('fclose', [], $this->id)); $this->id = null; - return $promise; + } else { + $this->closing = new Success; } - // FIXME: Should that really return new Success instead of an exception? - return new Success; + return $this->closing; } /** diff --git a/lib/UvHandle.php b/lib/UvHandle.php index ffbf23d..14bae6c 100644 --- a/lib/UvHandle.php +++ b/lib/UvHandle.php @@ -12,18 +12,39 @@ use Amp\Success; use function Amp\call; class UvHandle implements Handle { + /** @var UvPoll */ private $poll; - private $driver; - private $fh; - private $path; - private $mode; - private $size; + + /** @var \UVLoop */ private $loop; + + /** @var resource */ + private $fh; + + /** @var string */ + private $path; + + /** @var string */ + private $mode; + + /** @var int */ + private $size; + + /** @var int */ private $position; + + /** @var \SplQueue */ private $queue; + + /** @var bool */ private $isActive = false; + + /** @var bool */ private $writable = true; + /** @var \Amp\Promise|null */ + private $closing; + /** * @param \Amp\Loop\UvDriver $driver * @param UvPoll $poll Poll for keeping the loop active. @@ -33,7 +54,6 @@ class UvHandle implements Handle { * @param int $size */ public function __construct(Loop\UvDriver $driver, UvPoll $poll, $fh, string $path, string $mode, int $size) { - $this->driver = $driver; $this->poll = $poll; $this->fh = $fh; $this->path = $path; @@ -219,8 +239,12 @@ class UvHandle implements Handle { * {@inheritdoc} */ public function close(): Promise { + if ($this->closing) { + return $this->closing; + } + $deferred = new Deferred; - $this->poll->listen($deferred->promise()); + $this->poll->listen($this->closing = $deferred->promise()); \uv_fs_close($this->loop, $this->fh, function ($fh) use ($deferred) { // FIXME: Check for errors