Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Re-work Thread class using new nqp::ops.
  • Loading branch information
jnthn committed Feb 19, 2014
1 parent 2097d53 commit 9a717ab
Showing 1 changed file with 18 additions and 43 deletions.
61 changes: 18 additions & 43 deletions src/vm/jvm/core/Thread.pm
@@ -1,13 +1,9 @@
# This file contains early work on concurrency support for Rakudo on the JVM.
# The implementation is clearly VM specific, however the aim is to iterate
# towards a backend-independent API.

# Thread represents an OS-level thread. While it could be used directly, it
# is not the preferred way to work in Perl 6. It's a building block for the
# interesting things.
my class Thread {
# This thread's underlying JVM thread object.
has Mu $!jvm_thread;
# The VM-level thread handle.
has Mu $!vm_thread;

# Is the thread's lifetime bounded by that of the application, such
# that when it exits, so does the thread?
Expand All @@ -17,32 +13,26 @@ my class Thread {
has Str $.name;

submethod BUILD(:&code!, :$!app_lifetime as Bool = False, :$!name as Str = "<anon>") {
my $interop := nqp::jvmbootinterop();
my \JVMThread := $interop.typeForName('java.lang.Thread');
$!jvm_thread := JVMThread."constructor/new/(Ljava/lang/Runnable;)V"(
$interop.proxy('java.lang.Runnable', nqp::hash('run',
{
my $*THREAD = self;
code();
})));
$!jvm_thread.setDaemon(1) if $!app_lifetime;
$!vm_thread := nqp::newthread(
{ my $*THREAD = self; code(); },
$!app_lifetime ?? 1 !! 0);
}

method start(&code, *%adverbs) {
Thread.new(:&code, |%adverbs).jvm_start()
method start(Thread:U: &code, *%adverbs) {
Thread.new(:&code, |%adverbs).run()
}

method jvm_start(Thread:D:) {
$!jvm_thread.start();
method run(Thread:D:) {
nqp::threadrun($!vm_thread);
self
}

method id(Thread:D:) {
$!jvm_thread.getId();
nqp::p6box_i(nqp::threadid($!vm_thread));
}

method finish(Thread:D:) {
$!jvm_thread.'method/join/()V'();
nqp::threadjoin($!vm_thread);
self
}

Expand All @@ -51,30 +41,15 @@ my class Thread {
}

method yield(Thread:U:) {
nqp::jvmbootinterop().typeForName('java.lang.Thread').yield();
nqp::threadyield();
Nil
}
}

{
# This code is a little funky to avoid hitting jvmbootinterop at startup
# even if we never use anything that needs it. This is because it carries
# some cost and has a very bad interaction with the evalserver.
my int $not_yet = 1;
my $init_thread;
PROCESS::<$THREAD> := Proxy.new(
FETCH => -> | {
unless nqp::isconcrete($init_thread) || $not_yet {
my $interop := nqp::jvmbootinterop();
my \JVMThread := $interop.typeForName('java.lang.Thread');
$init_thread := nqp::create(Thread);
nqp::bindattr($init_thread, Thread, '$!jvm_thread', JVMThread.currentThread());
nqp::bindattr($init_thread, Thread, '$!app_lifetime', False);
nqp::bindattr($init_thread, Thread, '$!name', 'Initial thread');
}
$init_thread
},
STORE => -> | {
X::Assignment::RO.new.throw
});
$not_yet = 0;
my $init_thread := nqp::create(Thread);
nqp::bindattr($init_thread, Thread, '$!vm_thread', nqp::currentthread());
nqp::bindattr($init_thread, Thread, '$!app_lifetime', False);
nqp::bindattr($init_thread, Thread, '$!name', 'Initial thread');
PROCESS::<$THREAD> := $init_thread;
}

0 comments on commit 9a717ab

Please sign in to comment.