Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement Promise.sleep.
This produces a Promise that is kept after the specified time elapses.
Think of it like an asynchronous sleep, that doesn't block a thread.
  • Loading branch information
jnthn committed Aug 7, 2013
1 parent 6b386a7 commit 8ac6bb1
Showing 1 changed file with 20 additions and 4 deletions.
24 changes: 20 additions & 4 deletions src/vm/jvm/core/Threading.pm
Expand Up @@ -75,7 +75,7 @@ my class Promise {
})
}

method keep($result) {
method keep(Promise:D: $result) {
X::Promise::Code.new(attempted => 'keep').throw if &!code;
self!keep($result)
}
Expand All @@ -87,7 +87,7 @@ my class Promise {
$!result
}

method break($result) {
method break(Promise:D: $result) {
X::Promise::Code.new(attempted => 'break').throw if &!code;
self!break($result)
}
Expand All @@ -112,7 +112,7 @@ my class Promise {
$!then_lock.unlock();
}

method result() {
method result(Promise:D:) {
# One important missing optimization here is that if the promise is
# not yet started, then the work can be done immediately by the
# thing that is blocking on it.
Expand All @@ -127,7 +127,7 @@ my class Promise {
}
}

method then(&code) {
method then(Promise:D: &code) {
$!then_lock.lock();
if $!status == any(Failed, Completed) {
# Already have the result, schedule immediately.
Expand All @@ -143,6 +143,22 @@ my class Promise {
$then_promise
}
}

my Mu $timer;
method sleep(Promise:U: $seconds) {
once {
my Mu \Timer := nqp::jvmbootinterop().typeForName('java.util.Timer');
$timer := Timer.'constructor/new/(Z)V'(True);
Nil;
}
my $p = Promise.new;
$timer.'method/schedule/(Ljava/util/TimerTask;J)V'(
nqp::jvmbootinterop().proxy(
'java.util.TimerTask',
nqp::hash('run', -> { $p.keep(True) })),
($seconds * 1000).Int);
$p
}
}

# The ThreadPoolScheduler is a straightforward scheduler that maintains a
Expand Down

0 comments on commit 8ac6bb1

Please sign in to comment.