Skip to content

Commit

Permalink
Don't attempt non-blocking await if holding locks
Browse files Browse the repository at this point in the history
Locks are tied to a particular OS thread. Non-blocking await may move
code between OS threads. Therefore, if a lock is being held, then we
fall back on a real blocking await, so things work.

At present, various bits of the Supply internals rely on locks; this
thus fixes a lot of things that are broken, but also means that we
can't yet get all the benefit we'd like from non-blocking await.
Upcoming changes to various affected aspects of supplies will fix
this issue.
  • Loading branch information
jnthn committed Sep 15, 2017
1 parent 8d93846 commit f26d1e2
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/core/ThreadPoolScheduler.pm
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,17 @@ my class ThreadPoolScheduler does Scheduler {
$!queue := nqp::decont($queue);
}

sub holding-locks() {
nqp::p6bool(nqp::threadlockcount(nqp::currentthread()))
}

method await(Awaitable:D $a) {
holding-locks()
?? Awaiter::Blocking.await($a)
!! self!do-await($a)
}

method !do-await(Awaitable:D $a) {
my $handle := $a.get-await-handle;
if $handle.already {
$handle.success
Expand All @@ -37,6 +47,12 @@ my class ThreadPoolScheduler does Scheduler {
}

method await-all(Iterable:D \i) {
holding-locks()
?? Awaiter::Blocking.await-all(i)
!! self!do-await-all(i)
}

method !do-await-all(Iterable:D \i) {
# Collect results that are already available, and handles where the
# results are not yet available together with the matching insertion
# indices.
Expand Down

0 comments on commit f26d1e2

Please sign in to comment.