2

I'm trying to implement a thread-safe version of an mruby Rust binding.

mruby has a *mut MRState (a wrapper over mrb_state). You need to pass this *mut MRState when running mruby code. The mruby code has a Rust callback that it can call where it passes the same *mut MRState variable.

This *mut MRState is wrapped in a MRuby struct which I'm trying to make thread-safe. The problem is that if I wrap MRuby in a Mutex, it won't be able to re-enter inside of the Rust-written callback.

I'm currently wrapping MRuby in a RwLock but it's not very useful. The *mut MRState should be in a more permissive lock that lets it run inside of the callbacks.

How can I make MRuby work in both the callback and be forced to wait if called from different threads?

Apart from this, I'm having an issue with the *mut MRState inside MRuby which is not Send & Sync.

struct MRuby {
    mrb: *mut MRState,
    ...
}

This is an example of the callback.

// this callback will be run with a mrb_ function with takes
// *mut MRState as an argument, so it would need to lock
extern "C" callback(...) {
    // I need to use MRuby here which will make use of
    // its inner *mut MRState
    ...
}

This is an example of running mruby on a thread. mruby variable here could be an Arc<RwLock<MRuby>>.

thread::spawn(move || {
    mruby.run("*mruby code*"); // should run sequentially with
                               // with a lock on *mut MRState
});

The main reason why I want to implement this is not functionality. Actually, it's catch_panic which I need in order to catch any possible panics from the Rust callback. catch_panic runs in another thread, so I need to make MRuby thread-safe. Rust will stabilize std::panic only in 1.9.0 and until then I would need a working solution that doesn't need Rust nightly.

CORRECTION

Due to a bug in Rust's documentation generation, catch_panic is only marked as deprecated and not as unstable, even though it is. So a very simple solution is to just use std::panic and give up on thread-safety. I'm going to leave the question open, though, in case there is a good answer to this, even though my personal interest is lower now considering the aforementioned.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
dragostis
  • 2,574
  • 2
  • 20
  • 39
  • It rather sounds like you want a [reentrant lock](https://en.wikipedia.org/wiki/Reentrant_mutex) of some kind. – Shepmaster Mar 20 '16 at 14:59
  • Sure, but [`ReentrantMutex`](https://github.com/rust-lang/rust/blob/master/src/libstd/sys/common/remutex.rs#L24) is not even in `std`. :D – dragostis Mar 20 '16 at 15:01

0 Answers0