emacs-module-rs
emacs-module-rs copied to clipboard
Concurrency
I am playing around with exposing some of Rust's rayon
crate to Emacs. I've started with attempting to implement join
:
#[emacs::defun]
fn join<'a>(env: &Env, fa: Value<'a>, fb: Value<'a>) -> emacs::Result<()> {
env.message("racing: Entered join.")?;
let la = Lambda::new(fa);
let lb = Lambda::new(fb);
let a = || la.call();
let b = || lb.call();
env.message("racing: Invoking rayon...")?;
let (ra, rb) = rayon::join(a, b);
env.message(format!("ra: {}", ra.is_ok()))?;
env.message(format!("rb: {}", rb.is_ok()))?;
Ok(())
}
Ignoring the return type for the moment. After building and loading, I invoke it like this:
(racing-join (lambda () (message "Call from first lambda within Elisp!"))
(lambda () (message "Call from second lambda within Elisp!")))
Here, Lambda
is a wrapper type I've introduced to allow these evil trait instances:
unsafe impl<'a> Send for Lambda<'a> {}
unsafe impl<'a> Sync for Lambda<'a> {}
Otherwise the compiler complains of raw pointers (within Env
) being unSend
able.
My join
function "works" only if I replace b
with something that doesn't call lb
, the second lambda. Otherwise Emacs complete freezes as soon as I invoke the Lisp shown above. Poking around in the source code of your library, I suspect it has something to do with Env
. Having these unsafe
trait instances as I do might just be impossible.
Do you have any ideas as to why Emacs would entirely freeze (as opposed to just erroring) when I invoke racing-join
? Is Env
entirely thread-unsafe?
Thank you kindly.