77
88use std:: fs:: File ;
99use std:: io;
10- use std:: ops:: Deref ;
10+ use std:: ops:: { Deref , DerefMut } ;
1111use std:: os:: unix:: io:: { FromRawFd , IntoRawFd } ;
1212use std:: result:: Result ;
1313use std:: sync:: { Arc , Mutex , MutexGuard , RwLock , RwLockReadGuard , RwLockWriteGuard } ;
@@ -38,16 +38,37 @@ impl<'a, M: GuestAddressSpace> Deref for VringStateGuard<'a, M> {
3838 }
3939}
4040
41- /*
42- impl<'a, M: GuestAddressSpace> DerefMut for VringStateGuard<'a, M> {
41+ /// Struct to hold an exclusive reference to the underlying `VringState` object.
42+ pub enum VringStateMutGuard < ' a , M : GuestAddressSpace > {
43+ /// A reference to a `VringState` object.
44+ StateObject ( & ' a mut VringState < M > ) ,
45+ /// A `MutexGuard` for a `VringState` object.
46+ MutexGuard ( MutexGuard < ' a , VringState < M > > ) ,
47+ /// A `WriteGuard` for a `VringState` object.
48+ RwLockWriteGuard ( RwLockWriteGuard < ' a , VringState < M > > ) ,
49+ }
50+
51+ impl < ' a , M : GuestAddressSpace > Deref for VringStateMutGuard < ' a , M > {
52+ type Target = VringState < M > ;
53+
54+ fn deref ( & self ) -> & Self :: Target {
55+ match self {
56+ VringStateMutGuard :: StateObject ( v) => v,
57+ VringStateMutGuard :: MutexGuard ( v) => v. deref ( ) ,
58+ VringStateMutGuard :: RwLockWriteGuard ( v) => v. deref ( ) ,
59+ }
60+ }
61+ }
62+
63+ impl < ' a , M : GuestAddressSpace > DerefMut for VringStateMutGuard < ' a , M > {
4364 fn deref_mut ( & mut self ) -> & mut Self :: Target {
4465 match self {
45- VringStateGuard::StateObject(v) => v,
46- VringStateGuard::MutexGuard(v) => v.deref_mut(),
66+ VringStateMutGuard :: StateObject ( v) => v,
67+ VringStateMutGuard :: MutexGuard ( v) => v. deref_mut ( ) ,
68+ VringStateMutGuard :: RwLockWriteGuard ( v) => v. deref_mut ( ) ,
4769 }
4870 }
4971}
50- */
5172
5273pub trait VringT < M : GuestAddressSpace > {
5374 /// Create a new instance of Vring.
@@ -56,6 +77,9 @@ pub trait VringT<M: GuestAddressSpace> {
5677 /// Get an immutable reference to the kick event fd.
5778 fn get_ref ( & self ) -> VringStateGuard < M > ;
5879
80+ /// Get a mutable reference to the kick event fd.
81+ fn get_mut ( & mut self ) -> VringStateMutGuard < M > ;
82+
5983 /// Add an used descriptor into the used queue.
6084 fn add_used ( & mut self , desc_index : u16 , len : u32 ) -> Result < ( ) , VirtQueError > ;
6185
@@ -149,6 +173,10 @@ impl<M: GuestAddressSpace> VringT<M> for VringState<M> {
149173 VringStateGuard :: StateObject ( self )
150174 }
151175
176+ fn get_mut ( & mut self ) -> VringStateMutGuard < M > {
177+ VringStateMutGuard :: StateObject ( self )
178+ }
179+
152180 fn add_used ( & mut self , desc_index : u16 , len : u32 ) -> Result < ( ) , VirtQueError > {
153181 self . queue . add_used ( desc_index, len)
154182 }
@@ -256,6 +284,10 @@ impl<M: GuestAddressSpace> VringT<M> for VringMutex<M> {
256284 VringStateGuard :: MutexGuard ( self . state . lock ( ) . unwrap ( ) )
257285 }
258286
287+ fn get_mut ( & mut self ) -> VringStateMutGuard < M > {
288+ VringStateMutGuard :: MutexGuard ( self . lock ( ) )
289+ }
290+
259291 fn add_used ( & mut self , desc_index : u16 , len : u32 ) -> Result < ( ) , VirtQueError > {
260292 self . lock ( ) . add_used ( desc_index, len)
261293 }
@@ -346,6 +378,10 @@ impl<M: GuestAddressSpace> VringT<M> for VringRwLock<M> {
346378 VringStateGuard :: RwLockReadGuard ( self . state . read ( ) . unwrap ( ) )
347379 }
348380
381+ fn get_mut ( & mut self ) -> VringStateMutGuard < M > {
382+ VringStateMutGuard :: RwLockWriteGuard ( self . write_lock ( ) )
383+ }
384+
349385 fn add_used ( & mut self , desc_index : u16 , len : u32 ) -> Result < ( ) , VirtQueError > {
350386 self . write_lock ( ) . add_used ( desc_index, len)
351387 }
0 commit comments