1
0
mirror of https://github.com/danog/process.git synced 2024-11-26 20:24:43 +01:00

Don't kill on __destruct if streams are still used (#59)

This commit is contained in:
Niklas Keller 2021-12-14 00:53:30 +01:00 committed by GitHub
parent 51ed1d1bd0
commit b4403eee06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 8 deletions

View File

@ -0,0 +1,21 @@
<?php
namespace Amp\Process\Internal;
final class ProcHolder
{
private ProcessRunner $runner;
private ProcessHandle $handle;
public function __construct(ProcessRunner $runner, ProcessHandle $handle)
{
$this->runner = $runner;
$this->handle = $handle;
}
public function __destruct()
{
$this->runner->destroy($this->handle);
}
}

View File

@ -8,6 +8,7 @@ use Amp\Process\Internal\Posix\PosixRunner as PosixProcessRunner;
use Amp\Process\Internal\ProcessHandle;
use Amp\Process\Internal\ProcessRunner;
use Amp\Process\Internal\ProcessStatus;
use Amp\Process\Internal\ProcHolder;
use Amp\Process\Internal\Windows\WindowsRunner as WindowsProcessRunner;
use JetBrains\PhpStorm\ArrayShape;
use Revolt\EventLoop;
@ -16,6 +17,8 @@ final class Process
{
private static \WeakMap $driverRunner;
private static \WeakMap $procHolder;
/**
* Starts a new process.
*
@ -63,6 +66,14 @@ final class Process
$options
);
$procHolder = new ProcHolder($runner, $handle);
/** @psalm-suppress RedundantPropertyInitializationCheck */
self::$procHolder ??= new \WeakMap();
self::$procHolder[$handle->stdin] = $procHolder;
self::$procHolder[$handle->stdout] = $procHolder;
self::$procHolder[$handle->stderr] = $procHolder;
return new self($runner, $handle, $command, $workingDirectory, $envVars, $options);
}
@ -95,14 +106,6 @@ final class Process
$this->options = $options;
}
/**
* Stops the process if it is still running.
*/
public function __destruct()
{
$this->runner->destroy($this->handle);
}
public function __clone()
{
throw new \Error("Cloning " . self::class . " is not allowed.");

View File

@ -235,6 +235,19 @@ class ProcessTest extends AsyncTestCase
self::assertSame(0, $process->join());
}
public function testReadOutputAfterExitWithLongOutputDestructedProcess(): void
{
$process = Process::start(["php", __DIR__ . "/bin/worker.php"]);
$count = 128 * 1024 + 1;
$process->getStdin()->write("exit " . $count);
$stdout = $process->getStdout();
unset($process);
self::assertSame(\str_repeat(".", $count), buffer($stdout));
}
public function testKillPHPImmediately(): void
{
$socket = \stream_socket_server("tcp://127.0.0.1:10000");