Skip to content
This repository
tree: 3a54a7ec30
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 72 lines (62 sloc) 2.006 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
module Threads;

# Should be a role, since it can be applied to any class with minimal overhead
class Monitor is export {
    method enter() { Q:CgOp {
(rnull (rawscall System.Threading.Monitor.Enter (@ {self})))
} }
    method exit() { Q:CgOp {
(rnull (rawscall System.Threading.Monitor.Exit (@ {self})))
} }
    method pulse() { Q:CgOp {
(rnull (rawscall System.Threading.Monitor.Pulse (@ {self})))
} }
    method pulse_all() { Q:CgOp {
(rnull (rawscall System.Threading.Monitor.PulseAll (@ {self})))
} }
    method try_enter($t) { Q:CgOp {
(box Bool (rawscall System.Threading.Monitor.TryEnter (@ {self})
(cast int (obj_getnum {$t * 1000}))))
} }
    method wait() { Q:CgOp {
(box Bool (rawscall System.Threading.Monitor.Wait (@ {self})))
} }
    method try_wait($t) { Q:CgOp {
(box Bool (rawscall System.Threading.Monitor.Wait (@ {self})
(cast int (obj_getnum {$t * 1000}))))
} }
    # TODO exception handling
    method lock($f) { self.enter; $f(); self.exit }
}

sub lock($m,$f) is export { $m.lock($f); }

class ObjectPipe {
    has $!lock = Monitor.new;
    has $!queue = [];

    method get() {
        $!lock.enter;
        $!lock.wait until $!queue;
        my $value = shift $!queue;
        $!lock.exit;
        $value;
    }

    method put($x) {
        $!lock.enter;
        push $!queue, $x;
        $!lock.pulse;
        $!lock.exit;
    }
}

class Thread is export {
    has $!value;
    method new($func) {
        Q:CgOp { (box (@ {Thread}) (rawscall
Niecza.Kernel,Kernel.StartP6Thread:System.Threading.Thread (@ {$func}))) }
    }

    method join() {
        Q:CgOp { (rnull (rawcall Join (unbox clr:System.Threading.Thread (@ {self})))) }
    }

    method sleep($time) {
        my $t = $time * 1000;
        Q:CgOp { (rnull (rawscall System.Threading.Thread.Sleep (cast int (unbox num (@ {$t}))))) }
    }
}

sub sleep($time) is export { Thread.sleep($time) }
Something went wrong with that request. Please try again.