pub trait ThreadCreator: Send {
    fn spawn(
        &mut self,
        tc: Arc<Mutex<dyn ThreadCreator>>,
        code: String,
        globals: Option<Vec<(String, AtomicAVal)>>
    ) -> VVal;
fn new_env(&mut self) -> GlobalEnvRef; }
Expand description

This trait allows WLambda to create new threads. You can either use the DefaultThreadCreator default implementation or provide your own. Providing your own might be necessary if you want to customize how a thread is created.

If you only want to customize the GlobalEnv of newly created threads please consider just providing your own DefaultGlobalEnvCreator:

use std::sync::Arc;
use std::sync::Mutex;
use wlambda::compiler::GlobalEnv;
use wlambda::threads::{DefaultThreadCreator, FunctionGlobalEnvCreator};

let global_env = GlobalEnv::new_default();
global_env.borrow_mut().set_thread_creator(
    Some(Arc::new(Mutex::new(
        DefaultThreadCreator::new(
            FunctionGlobalEnvCreator::from(
                Box::new(|| GlobalEnv::new_default())))))));

If you want to influence more things on thread creation, see the followign example. Please refer to the source of DefaultThreadCreator for a comprehensive example.

use wlambda::*;
use wlambda::threads::*;
use std::sync::Arc;
use std::sync::Mutex;

// For simplicity we make detached threads here and don't pass any globals.
pub struct CustomThreadCreator();

impl ThreadCreator for CustomThreadCreator {
    fn new_env(&mut self) -> GlobalEnvRef {
        GlobalEnv::new_empty_default()
    }

    fn spawn(&mut self, tc: Arc<Mutex<dyn ThreadCreator>>,
             code: String,
             globals: Option<std::vec::Vec<(String, AtomicAVal)>>) -> VVal {

        let tcc = tc.clone();
        let hdl =
            std::thread::spawn(move || {
                let genv = GlobalEnv::new_empty_default();
                genv.borrow_mut().set_thread_creator(Some(tcc.clone()));

                let mut ctx = EvalContext::new(genv);

                match ctx.eval(&code) {
                    Ok(v) => AVal::from_vval(&v),
                    Err(e) => {
                        AVal::Err(
                            Box::new(
                                AVal::Str(format!("Error in Thread: {}", e))),
                            String::from("?"))
                    }
                }
            });
        VVal::None
    }
}

Required methods

Spawns a new thread with the given ThreadCreator. You need to pass the tc reference, so that the GlobalEnv of the thread also knows how to create new threads. You could even pass a different ThreadCreator for those.

code is a String containing WLambda code which is executed after the new thread has been spawned. globals is a mapping of global variable names and AtomicAVal instances that are loaded into the threads global environment. This is the only way to share data between threads.

Trait Implementations

Formats the value using the given formatter. Read more

Implementors