1/4: add real HSL to HHVM repo :)
[hiphop-php.git] / hphp / hsl / src / async / Condition.php
blob2518756c03ae91d46eedcbd21589747deef146d8
1 <?hh
2 /*
3 * Copyright (c) 2004-present, Facebook, Inc.
4 * All rights reserved.
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
9 */
11 namespace HH\Lib\Async;
13 /**
14 * A wrapper around ConditionWaitHandle that allows notification events
15 * to occur before the condition is awaited.
17 class Condition<T> {
18 private ?Awaitable<T> $condition = null;
20 /**
21 * Notify the condition variable of success and set the result.
23 final public function succeed(T $result): void {
24 if ($this->condition === null) {
25 $this->condition = async {
26 return $result;
28 } else {
29 invariant(
30 $this->condition is ConditionWaitHandle<_>,
31 'Unable to notify AsyncCondition twice',
33 /* HH_FIXME[4110]: Type error revealed by type-safe instanceof feature. See https://fburl.com/instanceof */
34 $this->condition->succeed($result);
38 /**
39 * Notify the condition variable of failure and set the exception.
41 final public function fail(\Exception $exception): void {
42 if ($this->condition === null) {
43 $this->condition = async {
44 throw $exception;
46 } else {
47 invariant(
48 $this->condition is ConditionWaitHandle<_>,
49 'Unable to notify AsyncCondition twice',
51 $this->condition->fail($exception);
55 /**
56 * Asynchronously wait for the condition variable to be notified and
57 * return the result or throw the exception received via notification.
59 * The caller must provide an Awaitable $notifiers (which must be a
60 * WaitHandle) that must not finish before the notification is received.
61 * This means $notifiers must represent work that is guaranteed to
62 * eventually trigger the notification. As long as the notification is
63 * issued only once, asynchronous execution unrelated to $notifiers is
64 * allowed to trigger the notification.
66 <<__ProvenanceSkipFrame>>
67 final public async function waitForNotificationAsync(
68 Awaitable<void> $notifiers,
69 ): Awaitable<T> {
70 if ($this->condition === null) {
71 $this->condition = ConditionWaitHandle::create($notifiers);
73 return await $this->condition;