Sam*_*rty 3 rust rwlock borrow-checker
我有一个类型的对象
Arc<RwLock<SessionData>>
Run Code Online (Sandbox Code Playgroud)
我有一种方法应该参考某种形式 SessionData
fn some_method(session: ...)
Run Code Online (Sandbox Code Playgroud)
我正在使用Rocket(Rust的Web框架),我不能直接调用该方法,因为它是由Rocket调用的。但是,我可以为它提供一个实现,该实现创建一个将传递给处理程序的对象。它看起来像这样:
impl<'a, 'r> request::FromRequest<'a, 'r> for SomeType {
type Error = ();
fn from_request(request: &'a request::Request<'r>) -> request::Outcome<Self, Self::Error> {
// return object here
}
}
Run Code Online (Sandbox Code Playgroud)
我想避免RwLock
直接返回一个,因为我希望处理程序将一个已经锁定的对象传递给它。但是,我无法返回引用或RwLockReadGuard
,因为它们都依赖RwLock
,这将超出范围。
相反,我尝试创建某种自给自足的类型,该类型将包含一个Arc<RwLock<SessionData>>
,包含此锁的锁保护并取消引用到一个SessionData
对象。
到目前为止,我已经尝试了以下几种组合:
Session
包含一个对象Arc<RwLock<SessionData>>
和一个RwLockReadGuard<SessionData>
Arc<RwLock<SessionData>>
和一个RwLockReadGuardRef<SessionData>
从所属-REF库。OwnedHandle
类型的对象。但是,我一直无法做自己想做的事,遇到了各种各样的终身借贷问题。
是否有可能创建一种自成一体的类似“句柄”的对象,同时包含指向它指向的对象的锁和锁保护装置?
这与如何返回对互斥量下的值的子值的引用中所描述的情况类似但略有不同。。在其中,MutexGuardRef
内部依赖Mutex
,如果Mutex
(或MyStruct
)超出范围,则内部不存在。为了实现类似的行为,我必须传递一个包含我的结构,RwLock
然后在方法内部进行锁定。很好,但是我想知道是否可以再走一步,并传递一个既独立又充当的结构,从而RwLockGuard
避免了手动锁定的需要。
基本上,我想将锁定RwLock
从值的客户端转移到提供者。
如为什么我不能在同一结构中存储值和对该值的引用中所述?,在某些情况下,租借板条箱允许使用自引用结构。
#[macro_use]
extern crate rental;
use std::sync::{Arc, RwLock};
struct SessionData;
impl SessionData {
fn hello(&self) -> u8 { 42 }
}
rental! {
mod owning_lock {
use std::sync::{Arc, RwLock, RwLockReadGuard};
#[rental(deref_suffix)]
pub struct OwningReadGuard<T>
where
T: 'static,
{
lock: Arc<RwLock<T>>,
guard: RwLockReadGuard<'lock, T>,
}
}
}
use owning_lock::OwningReadGuard;
fn owning_lock(session: Arc<RwLock<SessionData>>) -> OwningReadGuard<SessionData> {
OwningReadGuard::new(session, |s| s.read().unwrap())
}
fn main() {
let session = Arc::new(RwLock::new(SessionData));
let lock = owning_lock(session.clone());
println!("{}", lock.hello());
assert!(session.try_read().is_ok());
assert!(session.try_write().is_err());
drop(lock);
assert!(session.try_write().is_ok());
}
Run Code Online (Sandbox Code Playgroud)
也可以看看: