22
33namespace Revolt \EventLoop ;
44
5- use Revolt \EventLoop ;
6-
75/**
86 * Should be used to run and suspend the event loop instead of directly interacting with fibers.
97 *
108 * **Example**
119 *
1210 * ```php
13- * $suspension = Scheduler ::createSuspension();
11+ * $suspension = EventLoop ::createSuspension();
1412 *
1513 * $promise->then(fn ($value) => $suspension->resume($value), fn ($throwable) => $suspension->throw($throwable));
1614 *
@@ -23,29 +21,25 @@ final class Suspension
2321 private \Fiber $ scheduler ;
2422 private Driver $ driver ;
2523 private bool $ pending = false ;
24+ /** @var callable */
25+ private $ interrupt ;
2626
2727 /**
28- * Suspension constructor.
29- *
3028 * @param Driver $driver
3129 * @param \Fiber $scheduler
30+ * @param callable $interrupt
3231 *
3332 * @internal
3433 */
35- public function __construct (Driver $ driver , \Fiber $ scheduler )
34+ public function __construct (Driver $ driver , \Fiber $ scheduler, callable $ interrupt )
3635 {
3736 $ this ->driver = $ driver ;
37+ $ this ->scheduler = $ scheduler ;
38+ $ this ->interrupt = $ interrupt ;
3839 $ this ->fiber = \Fiber::getCurrent ();
3940
40- if ($ this ->fiber === $ scheduler ) {
41- throw new \Error (\sprintf (
42- 'Cannot call %s() within a scheduler microtask (%s::queue() callback) ' ,
43- __METHOD__ ,
44- EventLoop::class,
45- ));
46- }
47-
48- $ this ->scheduler = $ scheduler ;
41+ // User callbacks are always executed outside the event loop fiber, so this should always be false.
42+ \assert ($ this ->fiber !== $ this ->scheduler );
4943 }
5044
5145 public function throw (\Throwable $ throwable ): void
@@ -60,7 +54,7 @@ public function throw(\Throwable $throwable): void
6054 $ this ->driver ->queue ([$ this ->fiber , 'throw ' ], $ throwable );
6155 } else {
6256 // Suspend event loop fiber to {main}.
63- $ this ->driver -> interrupt (static fn () => throw $ throwable );
57+ ( $ this ->interrupt ) (static fn () => throw $ throwable );
6458 }
6559 }
6660
@@ -76,7 +70,7 @@ public function resume(mixed $value): void
7670 $ this ->driver ->queue ([$ this ->fiber , 'resume ' ], $ value );
7771 } else {
7872 // Suspend event loop fiber to {main}.
79- $ this ->driver -> interrupt (static fn () => $ value );
73+ ( $ this ->interrupt ) (static fn () => $ value );
8074 }
8175 }
8276
0 commit comments