-
Notifications
You must be signed in to change notification settings - Fork 24
/
threads.rs
65 lines (59 loc) · 1.87 KB
/
threads.rs
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
//! Multi-threaded elisp support.
use crate::core::{
env::Env,
gc::{Block, Context, RootSet},
object::{CloneIn, Object},
};
use rune_core::macros::root;
use rune_macros::defun;
use std::thread::{self, JoinHandle};
#[defun]
fn go(obj: Object) {
go_internal(obj);
}
fn go_internal(obj: Object) -> JoinHandle<()> {
let block = Block::new_local_unchecked();
let sexp = obj.clone_in(&block);
let raw = sexp.into_raw();
crate::debug::enable_debug();
thread::spawn(move || {
let roots = &RootSet::default();
let cx = &mut Context::from_block(block, roots);
root!(env, new(Env), cx);
let obj = unsafe { Object::from_raw(raw) };
root!(obj, cx);
_ = crate::interpreter::eval(obj, None, env, cx);
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_go() {
let roots = &RootSet::default();
let cx = &mut Context::new(roots);
let obj = cx.add("test string");
go_internal(obj).join().unwrap();
}
#[test]
fn test_go_eval() {
let roots = &RootSet::default();
let cx = &mut Context::new(roots);
let threads = [
go_internal(crate::reader::read("(if nil 1 2 3)", cx).unwrap().0),
go_internal(crate::reader::read("(progn (defvar foo 1) foo)", cx).unwrap().0),
go_internal(crate::reader::read("(progn (defvar foo 1) (makunbound 'foo) (let ((fn #'(lambda () (defvar foo 3))) (foo 7)) (funcall fn)) foo)", cx).unwrap().0),
];
for thread in threads {
thread.join().unwrap();
}
}
#[test]
fn test_go_message() {
let roots = &RootSet::default();
println!("hello main thread");
let cx = &mut Context::new(roots);
let obj = crate::reader::read("(message \"hello from thread\")", cx).unwrap().0;
go_internal(obj).join().unwrap();
}
}