rune/
threads.rs

1//! Multi-threaded elisp support.
2use crate::core::{
3    env::Env,
4    gc::{Block, Context, RootSet},
5    object::{CloneIn, Object},
6};
7use rune_core::macros::root;
8use rune_macros::defun;
9use std::thread::{self, JoinHandle};
10
11#[defun]
12fn go(obj: Object) {
13    go_internal(obj);
14}
15
16fn go_internal(obj: Object) -> JoinHandle<()> {
17    let block = Block::new_local_unchecked();
18    let sexp = obj.clone_in(&block);
19    let raw = sexp.into_raw();
20    crate::debug::enable_debug();
21    thread::spawn(move || {
22        let roots = &RootSet::default();
23        let cx = &mut Context::from_block(block, roots);
24        root!(env, new(Env), cx);
25        let obj = unsafe { Object::from_raw(raw) };
26        root!(obj, cx);
27        _ = crate::interpreter::eval(obj, None, env, cx);
28    })
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34
35    #[test]
36    fn test_go() {
37        let roots = &RootSet::default();
38        let cx = &mut Context::new(roots);
39        let obj = cx.add("test string");
40        go_internal(obj).join().unwrap();
41    }
42
43    #[test]
44    fn test_go_eval() {
45        let roots = &RootSet::default();
46        let cx = &mut Context::new(roots);
47        let threads = [
48            go_internal(crate::reader::read("(if nil 1 2 3)", cx).unwrap().0),
49            go_internal(crate::reader::read("(progn (defvar foo 1) foo)", cx).unwrap().0),
50            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),
51        ];
52        for thread in threads {
53            thread.join().unwrap();
54        }
55    }
56
57    #[test]
58    fn test_go_message() {
59        let roots = &RootSet::default();
60        println!("hello main thread");
61        let cx = &mut Context::new(roots);
62        let obj = crate::reader::read("(message \"hello from thread\")", cx).unwrap().0;
63        go_internal(obj).join().unwrap();
64    }
65}