Skip to content

Instantly share code, notes, and snippets.

@jjergus
Created July 23, 2020 22:28
Show Gist options
  • Save jjergus/bcbeb535e1945d82c1a72e503374afba to your computer and use it in GitHub Desktop.
Save jjergus/bcbeb535e1945d82c1a72e503374afba to your computer and use it in GitHub Desktop.
diff --git a/src/network/_Private/CancelablePoller.php b/src/network/_Private/CancelablePoller.php
deleted file mode 100644
index 9cc13c8..0000000
--- a/src/network/_Private/CancelablePoller.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?hh
-/*
- * Copyright (c) 2004-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- */
-
-namespace HH\Lib\_Private\_Network;
-
-use namespace HH\Lib\OS;
-use namespace HH\Lib\_Private\_OS;
-
-final class CancelablePoller {
- private int $nextID = 0;
- private dict<int, Awaitable<mixed>> $polls = dict[];
-
- public async function pollAsync(
- OS\FileDescriptor $fd,
- int $events,
- int $timeout_ns,
- ): Awaitable<int> {
- $id = $this->nextID;
- $this->nextID++;
-
- $awaitable = _OS\poll_async($fd, $events, $timeout_ns);
- $this->polls[$id] = $awaitable;
- try {
- return await $awaitable;
- } catch (PollCancelledException $e) {
- return $e->getResult();
- } finally {
- unset($this->polls[$id]);
- }
- }
-
- public function cancelAll(int $result): void {
- $ex = new PollCancelledException($result);
- foreach ($this->polls as $poll) {
- \HH\Asio\cancel($poll, $ex);
- }
- }
-}
diff --git a/src/network/_Private/PollCancelledException.php b/src/network/_Private/PollCancelledException.php
deleted file mode 100644
index e4a6683..0000000
--- a/src/network/_Private/PollCancelledException.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?hh
-/*
- * Copyright (c) 2004-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- */
-
-namespace HH\Lib\_Private\_Network;
-
-final class PollCancelledException extends \Exception {
- public function __construct(private int $result) {
- parent::__construct();
- }
-
- public function getResult(): int {
- return $this->result;
- }
-}
diff --git a/src/network/_Private/socket_accept_async.php b/src/network/_Private/socket_accept_async.php
index c0a5005..a571bc3 100644
--- a/src/network/_Private/socket_accept_async.php
+++ b/src/network/_Private/socket_accept_async.php
@@ -15,23 +15,20 @@ use namespace HH\Lib\_Private\_OS;
/** Accept a socket connection, waiting if necessary */
async function socket_accept_async(
OS\FileDescriptor $server,
- CancelablePoller $poller,
): Awaitable<OS\FileDescriptor> {
try {
list($fd, $_addr) = OS\accept($server);
return $fd;
} catch (OS\BlockingIOException $_) {
// accept (3P) defines select() as indicating the FD ready for read when there's a connection
- $result = await $poller->pollAsync(
- $server,
- \STREAM_AWAIT_READ, /* timeout = */
- 0,
- );
- if ($result === \STREAM_AWAIT_CLOSED) {
- _OS\throw_errno(
- OS\Errno::ECONNABORTED,
- "Server socket closed while waiting for connection",
+ try {
+ await _OS\poll_async(
+ $server,
+ \STREAM_AWAIT_READ, /* timeout = */
+ 0,
);
+ } catch (_OS\ErrnoException $e) {
+ _OS\throw_errno($e->getCode() as OS\Errno, '%s', $e->getMessage());
}
list($fd, $_addr) = OS\accept($server);
return $fd;
diff --git a/src/tcp/Server.php b/src/tcp/Server.php
index c900676..83e19bb 100644
--- a/src/tcp/Server.php
+++ b/src/tcp/Server.php
@@ -17,10 +17,7 @@ final class Server implements Network\Server<CloseableSocket> {
/** Host and port */
const type TAddress = (string, int);
- private _Network\CancelablePoller $poller;
-
private function __construct(private OS\FileDescriptor $impl) {
- $this->poller = new _Network\CancelablePoller();
}
/** Create a bound and listening instance */
@@ -106,7 +103,7 @@ final class Server implements Network\Server<CloseableSocket> {
}
public async function nextConnectionAsync(): Awaitable<CloseableSocket> {
- return await _Network\socket_accept_async($this->impl, $this->poller)
+ return await _Network\socket_accept_async($this->impl)
|> new _TCP\CloseableTCPSocket($$);
}
@@ -127,6 +124,5 @@ final class Server implements Network\Server<CloseableSocket> {
public function stopListening(): void {
OS\close($this->impl);
- $this->poller->cancelAll(\STREAM_AWAIT_CLOSED);
}
}
diff --git a/src/unix/Server.php b/src/unix/Server.php
index 554446c..cd6336f 100644
--- a/src/unix/Server.php
+++ b/src/unix/Server.php
@@ -17,10 +17,7 @@ final class Server implements Network\Server<CloseableSocket> {
/** Path */
const type TAddress = string;
- private _Network\CancelablePoller $poller;
-
private function __construct(private OS\FileDescriptor $impl) {
- $this->poller = new _Network\CancelablePoller();
}
/** Create a bound and listening instance */
@@ -37,7 +34,7 @@ final class Server implements Network\Server<CloseableSocket> {
}
public async function nextConnectionAsync(): Awaitable<CloseableSocket> {
- return await _Network\socket_accept_async($this->impl, $this->poller)
+ return await _Network\socket_accept_async($this->impl)
|> new _Unix\CloseableSocket($$);
}
@@ -48,6 +45,5 @@ final class Server implements Network\Server<CloseableSocket> {
public function stopListening(): void {
OS\close($this->impl);
- $this->poller->cancelAll(\STREAM_AWAIT_CLOSED);
}
}
diff --git a/tests/tcp/HSLTCPTest.php b/tests/tcp/HSLTCPTest.php
index 40e7262..cfeb4ea 100644
--- a/tests/tcp/HSLTCPTest.php
+++ b/tests/tcp/HSLTCPTest.php
@@ -198,6 +198,7 @@ final class HSLTCPTest extends HackTest {
$s->stopListening();
$ex = expect(async () ==> await $accept_awaitable)->toThrow(
OS\ErrnoException::class,
+ 'Operation cancelled because FileDescriptor was closed.',
);
expect($ex->getErrno())->toEqual(OS\Errno::ECONNABORTED);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment