From 9df596232b6e82f6105f51a5ceb08503aada8d21 Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Mon, 21 Mar 2022 08:45:21 -0700 Subject: [PATCH] Add Condition->trySucceed and Condition->tryFail (#185) Summary: It would allow for use cases like this: ``` async function outer(): Awaitable { await wait_for_notification_async( async $notifyee ==> { concurrent { await async { await gen_usleep(100); $notifyee->trySucceed("fast condition"); } await async { await gen_usleep(10000000000); $notifyee->trySucceed("slow condition"); } } } ); } ``` X-link: https://github.com/hhvm/hsl/pull/185 Reviewed By: fredemmott Differential Revision: D34903436 Pulled By: Atry fbshipit-source-id: 859d72707fa338df22522c778c35f47c23497746 --- hphp/hsl/src/async/Condition.php | 44 ++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/hphp/hsl/src/async/Condition.php b/hphp/hsl/src/async/Condition.php index 64acefabcf1edd..eb277dc3f3ae00 100644 --- a/hphp/hsl/src/async/Condition.php +++ b/hphp/hsl/src/async/Condition.php @@ -21,34 +21,58 @@ class Condition { * Notify the condition variable of success and set the result. */ final public function succeed(T $result): void { + invariant($this->trySucceed($result), 'Unable to notify Condition twice'); + } + + /** + * Notify the condition variable of failure and set the exception. + */ + final public function fail(\Exception $exception): void { + invariant($this->tryFail($exception), 'Unable to notify Condition twice'); + } + + /** + * Notify the condition variable of success and set the $result. + * + * @return + * true if the condition is set to $result successfully, false if the + * condition was previously set to another result or exception. + */ + final public function trySucceed(T $result): bool { if ($this->condition === null) { $this->condition = async { return $result; }; + return true; } else { - invariant( - $this->condition is ConditionWaitHandle<_>, - 'Unable to notify AsyncCondition twice', - ); + if (!($this->condition is ConditionWaitHandle<_>)) { + return false; + } /* HH_FIXME[4110]: Type error revealed by type-safe instanceof feature. See https://fburl.com/instanceof */ $this->condition->succeed($result); + return true; } } /** - * Notify the condition variable of failure and set the exception. + * Notify the condition variable of failure and set the $exception. + * + * @return + * true if the condition is set to $exception successfully, false if the + * condition was previously set to another result or exception. */ - final public function fail(\Exception $exception): void { + final public function tryFail(\Exception $exception): bool { if ($this->condition === null) { $this->condition = async { throw $exception; }; + return true; } else { - invariant( - $this->condition is ConditionWaitHandle<_>, - 'Unable to notify AsyncCondition twice', - ); + if (!($this->condition is ConditionWaitHandle<_>)) { + return false; + } $this->condition->fail($exception); + return true; } }