[][src]Module wlambda::threads

Threading API:

#[cfg(feature="regex")]
{
    use wlambda::vval::*;

    // Get some random user thread:
    let mut ctx = wlambda::EvalContext::new_default();

    let mut msg_handle = wlambda::threads::MsgHandle::new();
    // You may register on multiple threads, but only one thread can use it at a time.
    let sender = msg_handle.sender();
    sender.register_on_as(&mut ctx, "worker");

    let t = std::thread::spawn(move || {
        let quit = std::rc::Rc::new(std::cell::RefCell::new(false));

        let global_t = wlambda::GlobalEnv::new_default();

        let qr = quit.clone();
        global_t.borrow_mut()
            .add_func("thread:quit", move |env: &mut Env, _argc: usize| {
                *qr.borrow_mut() = true;
                Ok(VVal::Nul)
            }, Some(0), Some(0));

        let mut ctx = wlambda::EvalContext::new(global_t);

        ctx.eval("!:global X = 123");

        // msg_handle.run(&mut ctx);
        // or alternatively:

        loop {
            // Tries to handle one RPC call within 10ms.
            if let None = msg_handle.step(&mut ctx, &std::time::Duration::from_millis(10)) {
                break;
            }

            if *quit.borrow() { break; }

            // do some other work here, that is not blocking the thread indefinitely.
        }
    });

    // Calls the global `displayln` in the Worker thread with the supplied arguments.
    ctx.eval("worker_call :displayln \"hello world from worker thread!\";").unwrap();

    ctx.eval("std:assert_eq (worker_call :std:eval \"X\") 123;").unwrap();

    sender.call("thread:quit", VVal::Nul);

    t.join();
}

The alternative async messaging API, that does not provide any return values from the Thread. However, you could theoretically generate two message handles for a two way communication.

#[cfg(feature="regex")]
{
    use wlambda::vval::*;

    // Get some random user thread:
    let mut ctx = wlambda::EvalContext::new_default();

    let mut msg_handle = wlambda::threads::MsgHandle::new();

    let sender = msg_handle.sender();

    // You may register on multiple threads, but only one thread can use it at a time.
    sender.register_on_as(&mut ctx, "worker");

    let t = std::thread::spawn(move || {
        let mut ctx  = wlambda::EvalContext::new_default();

        // This also implicitly defines a thread:quit:
        msg_handle.run(&mut ctx);
    });

    sender.call("thread:quit", VVal::Nul);

    t.join();
}

Structs

MsgHandle

This a messaging handle for providing receiver and sender handles for the inter thread communication of WLambda instances.

Receiver
Sender

The Sender sends RPC calls to the Receiver thread. Any values passed by WLambda code are serialized into msgpack internally and transmitted to the thread in String form. This means, your values must not be cyclic or contain non serializable data like external handles.