我正在尝试实现mruby Rust绑定的线程安全版本。
mruby有一个*mut MRState
(一个超过mrb_state
的包装器)。运行mruby代码时需要传递此*mut MRState
。 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
在另一个线程中运行,因此我需要使catch_panic
线程安全。 Rust只会在1.9.0中稳定std::panic
,直到那时我需要一个每晚都不需要Rust的工作解决方案。
CORRECTION
由于Rust的文档生成中存在错误,std::panic
仅被标记为已弃用且不稳定,即使它是。所以一个非常简单的解决方案就是使用@IBOutlet var tview: UITableView!
var currentDate: NSDate = NSDate()
override func viewDidLoad(){
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: "refresh:", forControlEvents: .ValueChanged)
refreshControl.attributedTitle = NSAttributedString(string: "last updated on \(currentDate)")
tview.separatorStyle = UITableViewCellSeparatorStyle.None
tview.addSubview(refreshControl)
}
func refresh(refreshControl: UIRefreshControl) {
refreshControl.attributedTitle = NSAttributedString(string: "last updated on \(currentDate)")
fetchRequests()
}
并放弃线程安全性。不过,如果有一个很好的答案,我会打开这个问题,即使考虑到前面提到我的个人兴趣较低。