1
0
mirror of https://github.com/danog/process.git synced 2024-11-30 04:39:04 +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\ProcessHandle;
use Amp\Process\Internal\ProcessRunner; use Amp\Process\Internal\ProcessRunner;
use Amp\Process\Internal\ProcessStatus; use Amp\Process\Internal\ProcessStatus;
use Amp\Process\Internal\ProcHolder;
use Amp\Process\Internal\Windows\WindowsRunner as WindowsProcessRunner; use Amp\Process\Internal\Windows\WindowsRunner as WindowsProcessRunner;
use JetBrains\PhpStorm\ArrayShape; use JetBrains\PhpStorm\ArrayShape;
use Revolt\EventLoop; use Revolt\EventLoop;
@ -16,6 +17,8 @@ final class Process
{ {
private static \WeakMap $driverRunner; private static \WeakMap $driverRunner;
private static \WeakMap $procHolder;
/** /**
* Starts a new process. * Starts a new process.
* *
@ -63,6 +66,14 @@ final class Process
$options $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); return new self($runner, $handle, $command, $workingDirectory, $envVars, $options);
} }
@ -95,14 +106,6 @@ final class Process
$this->options = $options; $this->options = $options;
} }
/**
* Stops the process if it is still running.
*/
public function __destruct()
{
$this->runner->destroy($this->handle);
}
public function __clone() public function __clone()
{ {
throw new \Error("Cloning " . self::class . " is not allowed."); throw new \Error("Cloning " . self::class . " is not allowed.");

View File

@ -235,6 +235,19 @@ class ProcessTest extends AsyncTestCase
self::assertSame(0, $process->join()); 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 public function testKillPHPImmediately(): void
{ {
$socket = \stream_socket_server("tcp://127.0.0.1:10000"); $socket = \stream_socket_server("tcp://127.0.0.1:10000");