Skip to content

Commit 52e08c0

Browse files
committed
Forward cancellation to connecting socket reads
1 parent 5bd74a0 commit 52e08c0

File tree

1 file changed

+17
-15
lines changed

1 file changed

+17
-15
lines changed

src/Internal/Windows/SocketConnector.php

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
use Amp\ByteStream\ReadableResourceStream;
66
use Amp\ByteStream\WritableResourceStream;
77
use Amp\Cancellation;
8+
use Amp\CancelledException;
89
use Amp\ForbidCloning;
910
use Amp\ForbidSerialization;
1011
use Amp\Process\Internal\ProcessStatus;
1112
use Amp\Process\Internal\ProcessStreams;
1213
use Amp\Process\ProcessException;
14+
use Amp\TimeoutCancellation;
1315
use Revolt\EventLoop;
1416
use function Amp\async;
1517

@@ -70,7 +72,7 @@ public function connectPipes(WindowsHandle $handle, Cancellation $cancellation):
7072
$handle->startBarrier->await($cancellation);
7173

7274
$controlPipe = new ReadableResourceStream($handle->sockets[0]);
73-
$handle->pid = $this->readChildPid($controlPipe);
75+
$handle->pid = $this->readChildPid($controlPipe, $cancellation);
7476
} catch (\Throwable $exception) {
7577
foreach ($handle->sockets as $socket) {
7678
\fclose($socket);
@@ -97,9 +99,9 @@ public function connectPipes(WindowsHandle $handle, Cancellation $cancellation):
9799
$handle->exitCodeStream = $controlPipe;
98100

99101
$stdin = \WeakReference::create($streams->stdin);
100-
async(function () use ($handle, $stdin) {
102+
async(function () use ($handle, $stdin, $cancellation): void {
101103
try {
102-
$exitCode = $this->readExitCode($handle->exitCodeStream);
104+
$exitCode = $this->readExitCode($handle->exitCodeStream, $cancellation);
103105

104106
$handle->joinDeferred->complete($exitCode);
105107
} catch (\Throwable) {
@@ -128,11 +130,11 @@ private function acceptClient(): void
128130
throw new \Error("Failed to set client socket to non-blocking mode");
129131
}
130132

131-
async(function () use ($socket) {
133+
async(function () use ($socket): void {
132134
try {
133-
$handle = $this->performClientHandshake($socket);
135+
$handle = $this->performClientHandshake($socket, new TimeoutCancellation(5));
134136
$handle->startBarrier->arrive();
135-
} catch (HandshakeException $e) {
137+
} catch (HandshakeException|CancelledException $e) {
136138
/** @psalm-suppress InvalidScalarArgument */
137139
\fwrite($socket, \chr(SignalCode::HANDSHAKE_ACK) . \chr($e->getCode()));
138140
\fclose($socket);
@@ -145,13 +147,13 @@ private function acceptClient(): void
145147
*
146148
* @throws HandshakeException
147149
*/
148-
public function performClientHandshake($socket): WindowsHandle
150+
public function performClientHandshake($socket, Cancellation $cancellation): WindowsHandle
149151
{
150152
$stream = new ReadableResourceStream($socket);
151153

152154
$packet = \unpack(
153155
'Csignal/Npid/Cstream_id/a*client_token',
154-
$this->read($stream, self::SECURITY_TOKEN_SIZE + 6)
156+
$this->read($stream, $cancellation, length: self::SECURITY_TOKEN_SIZE + 6)
155157
);
156158

157159
// validate the client's handshake
@@ -193,7 +195,7 @@ public function performClientHandshake($socket): WindowsHandle
193195
throw new HandshakeException(HandshakeStatus::NO_LONGER_PENDING);
194196
}
195197

196-
$packet = \unpack('Csignal/Cstatus', $this->read($stream, 2));
198+
$packet = \unpack('Csignal/Cstatus', $this->read($stream, $cancellation, length: 2));
197199

198200
if ($packet['signal'] !== SignalCode::HANDSHAKE_ACK || $packet['status'] !== HandshakeStatus::SUCCESS) {
199201
throw new HandshakeException(HandshakeStatus::ACK_STATUS_ERROR);
@@ -207,9 +209,9 @@ public function performClientHandshake($socket): WindowsHandle
207209
/**
208210
* @return positive-int
209211
*/
210-
private function readChildPid(ReadableResourceStream $stream): int
212+
private function readChildPid(ReadableResourceStream $stream, Cancellation $cancellation): int
211213
{
212-
$packet = \unpack('Csignal/Npid', $this->read($stream, 5));
214+
$packet = \unpack('Csignal/Npid', $this->read($stream, $cancellation, length: 5));
213215
if ($packet['signal'] !== SignalCode::CHILD_PID) {
214216
throw new HandshakeException(HandshakeStatus::SIGNAL_UNEXPECTED);
215217
}
@@ -219,9 +221,9 @@ private function readChildPid(ReadableResourceStream $stream): int
219221
return $pid;
220222
}
221223

222-
private function readExitCode(ReadableResourceStream $stream): int
224+
private function readExitCode(ReadableResourceStream $stream, Cancellation $cancellation): int
223225
{
224-
$packet = \unpack('Csignal/Ncode', $this->read($stream, 5));
226+
$packet = \unpack('Csignal/Ncode', $this->read($stream, $cancellation, length: 5));
225227

226228
if ($packet['signal'] !== SignalCode::EXIT_CODE) {
227229
throw new HandshakeException(HandshakeStatus::SIGNAL_UNEXPECTED);
@@ -230,15 +232,15 @@ private function readExitCode(ReadableResourceStream $stream): int
230232
return (int) $packet['code'];
231233
}
232234

233-
private function read(ReadableResourceStream $stream, int $length): string
235+
private function read(ReadableResourceStream $stream, Cancellation $cancellation, int $length): string
234236
{
235237
$buffer = '';
236238

237239
do {
238240
$remaining = $length - \strlen($buffer);
239241
\assert($remaining > 0);
240242

241-
$chunk = $stream->read(limit: $remaining);
243+
$chunk = $stream->read($cancellation, limit: $remaining);
242244
if ($chunk === null) {
243245
break;
244246
}

0 commit comments

Comments
 (0)