异步友好的 RefCell 可防止跨等待点借用

问题描述 投票:0回答:1

是否有任何方法可以创建类似 RefCell 的数据结构,以防止在等待点上发生借用?我有一个单线程异步运行时,并且我的对象的内部状态可以在单个线程内安全地发生变化。然而,RefCell 是危险的,因为如果我不小心在等待点上持有借用,那么调用者对实际上安全的变异 API 进行重叠调用就不再安全了(他们会因为重复借用而恐慌)。

我想互斥锁+工作窃取运行时一定存在类似的问题。

我猜我可以拥有一个仅公开基于闭包的接口的 RefCell 包装器:

fn guarded_mut<F: FnOnce(&mut T)>(&self, cb: F)

但是如果我希望能够轻松地从中转发返回值,我不知道如何安全地防范期货:

fn guarded_mut<R, F: FnOnce(&mut T) -> R>(&self, cb: F) -> R

guarded_mut(|interior| async move {
}).await;

也许受保护的 API 只是为了防止这种情况发生,因为内部的生命周期比 R 的生命周期短?

rust async-await
1个回答
0
投票

在多线程运行时,这会自动发生,因为

RefCell
的借用值(
Ref
RefMut
)不是
Send
。因此,在等待点持有一个将使未来变得不
Send

如果您使用单线程运行时,则没有

Send
约束,因此没有机制可以阻止在等待点上持有
Ref
/
RefMut
。 Rust 没有“等待安全”作为一流概念,因此无法静态检查。

© www.soinside.com 2019 - 2024. All rights reserved.