Как я могу заставить указатель C ждать, если вызывается из другого потока, но работать в обратном вызове?
Я пытаюсь реализовать поточно- ориентированную версию Mruby Rust.
у мруби есть *mut MRState
(обертка над mrb_state
). Вам нужно пройти это *mut MRState
при запуске кода Mruby. Код Mruby имеет обратный вызов Rust, который он может вызывать там, где он проходит тот же *mut MRState
переменная.
это *mut MRState
завернут в MRuby
struct
который я пытаюсь сделать потокобезопасным. Проблема в том, что если я заверну MRuby
в Mutex
, он не сможет повторно войти внутрь написанного на Rust обратного вызова.
Я в настоящее время упаковываю MRuby
в RwLock
но это не очень полезно. *mut MRState
должен быть в более разрешающей блокировке, которая позволяет ему работать внутри обратных вызовов.
Как я могу сделать MRuby
работать как в обратном вызове и быть вынужденным ждать, если вызов из разных потоков?
Помимо этого, у меня есть проблема с *mut MRState
внутри MRuby
который не Send
& Sync
,
struct MRuby {
mrb: *mut MRState,
...
}
Это пример обратного вызова.
// 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
...
}
Это пример запуска mruby в потоке. mruby
переменная здесь может быть Arc<RwLock<MRuby>>
,
thread::spawn(move || {
mruby.run("*mruby code*"); // should run sequentially with
// with a lock on *mut MRState
});
Основная причина, почему я хочу реализовать это не функциональность. На самом деле, это catch_panic
что мне нужно для того, чтобы поймать любую возможную панику от обратного вызова Rust. catch_panic
работает в другой теме, поэтому мне нужно сделать MRuby
потокобезопасный. Ржавчина стабилизируется std::panic
только в 1.9.0 и до тех пор мне нужно рабочее решение, которое не требует Rust по ночам.
КОРРЕКЦИЯ
Из-за ошибки в генерации документации Rust, catch_panic
помечается как устаревшее и не нестабильное, даже если это так. Так что очень простое решение - просто использовать std::panic
и отказаться от безопасности потоков. Я собираюсь оставить этот вопрос открытым, хотя, в случае хорошего ответа на него, даже если мой личный интерес сейчас ниже, учитывая вышеизложенное.