library_tests/
test_threading.rs

1use std::panic;
2
3use wolfram_library_link::{
4    self as wll,
5    expr::{Expr, Symbol},
6};
7
8#[wll::export]
9fn test_runtime_function_from_main_thread() -> bool {
10    let expr = Expr::normal(Symbol::new("System`Plus"), vec![
11        Expr::from(2),
12        Expr::from(2),
13    ]);
14
15    wll::evaluate(&expr) == Expr::from(4)
16}
17
18#[wll::export]
19fn test_runtime_function_from_non_main_thread() -> String {
20    let child = std::thread::spawn(|| {
21        panic::set_hook(Box::new(|_| {
22            // Do nothing, just to avoid printing panic message to stderr.
23        }));
24
25        let result = panic::catch_unwind(|| {
26            wll::evaluate(&Expr::normal(Symbol::new("System`Plus"), vec![
27                Expr::from(2),
28                Expr::from(2),
29            ]))
30        });
31
32        // Restore the previous (default) hook.
33        let _ = panic::take_hook();
34
35        result
36    });
37
38    let result = child.join().unwrap();
39
40    match result {
41        Ok(_) => "didn't panic".to_owned(),
42        // We expect the thread to panic
43        Err(panic) => {
44            if let Some(str) = panic.downcast_ref::<&str>() {
45                format!("PANIC: {}", str)
46            } else if let Some(string) = panic.downcast_ref::<String>() {
47                format!("PANIC: {}", string)
48            } else {
49                "PANIC".to_owned()
50            }
51        },
52    }
53}