diff src/core.c/asyncops.pm6 @ 0:c341f82e7ad7 default tip

Rakudo branch in cr.ie.u-ryukyu.ac.jp
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 26 Dec 2019 16:50:27 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core.c/asyncops.pm6	Thu Dec 26 16:50:27 2019 +0900
@@ -0,0 +1,56 @@
+# Waits for a promise to be kept or a channel to be able to receive a value
+# and, once it can, unwraps or returns the result. Under Perl 6.c, await will
+# really block the calling thread. In 6.d, if the thread is on the thread pool
+# then a continuation will be taken, and the thread is freed up.
+
+my role X::Await::Died {
+    has $.await-backtrace;
+    multi method gist(::?CLASS:D:) {
+        "An operation first awaited:\n" ~
+            ((try $!await-backtrace ~ "\n") // '<unknown location>') ~
+            "Died with the exception:\n" ~
+            callsame().indent(4)
+    }
+}
+
+proto sub await(|) {*}
+multi sub await() {
+    die "Must specify a Promise or Channel to await on (got an empty list)";
+}
+multi sub await(Any:U $x) {
+    die "Must specify a defined Promise, Channel, or Supply to await on (got an undefined $x.^name())";
+}
+multi sub await(Any:D $x) {
+    die "Must specify a Promise, Channel, or Supply to await on (got a $x.^name())";
+}
+multi sub await(Promise:D $p) {
+    CATCH {
+        unless nqp::istype($_, X::Await::Died) {
+            ($_ but X::Await::Died(Backtrace.new(5))).rethrow
+        }
+    }
+    my $*RAKUDO-AWAIT-BLOCKING := True;
+    $*AWAITER.await($p)
+}
+multi sub await(Channel:D $c) {
+    CATCH {
+        unless nqp::istype($_, X::Await::Died) {
+            ($_ but X::Await::Died(Backtrace.new(5))).rethrow
+        }
+    }
+    my $*RAKUDO-AWAIT-BLOCKING := True;
+    $*AWAITER.await($c)
+}
+multi sub await(Supply:D $s) {
+    CATCH {
+        unless nqp::istype($_, X::Await::Died) {
+            ($_ but X::Await::Died(Backtrace.new(5))).rethrow
+        }
+    }
+    my $*RAKUDO-AWAIT-BLOCKING := True;
+    $*AWAITER.await($s)
+}
+multi sub await(Iterable:D $i) { eager $i.eager.map({ await $_ }) }
+multi sub await(*@awaitables)  { eager @awaitables.eager.map({await $_}) }
+
+# vim: ft=perl6 expandtab sw=4