@@ -419,39 +419,23 @@ impl VirtqUsedElem {
419419
420420unsafe impl ByteValued for VirtqUsedElem { }
421421
422- /// Struct to hold an exclusive reference to the underlying `QueueState` object.
423- pub enum QueueStateGuard < ' a > {
424- /// A reference to a `QueueState` object.
425- StateObject ( & ' a mut QueueState ) ,
426- /// A `MutexGuard` for a `QueueState` object.
427- MutexGuard ( MutexGuard < ' a , QueueState > ) ,
428- }
429-
430- impl < ' a > Deref for QueueStateGuard < ' a > {
431- type Target = QueueState ;
432-
433- fn deref ( & self ) -> & Self :: Target {
434- match self {
435- QueueStateGuard :: StateObject ( v) => v,
436- QueueStateGuard :: MutexGuard ( v) => v. deref ( ) ,
437- }
438- }
439- }
440-
441- impl < ' a > DerefMut for QueueStateGuard < ' a > {
442- fn deref_mut ( & mut self ) -> & mut Self :: Target {
443- match self {
444- QueueStateGuard :: StateObject ( v) => v,
445- QueueStateGuard :: MutexGuard ( v) => v. deref_mut ( ) ,
446- }
447- }
422+ /// Lifetime-generic guard associated to a QueueStateT. In practice,
423+ /// instead of having a `QueueStateT::Guard<'a>` generic associated type,
424+ /// you have to write `<QueueStateT::Guard as QueueStateGuard<'a>>::Out`.
425+ pub trait QueueStateGuard < ' a > {
426+ /// Type of the guard returned by the `lock` method.
427+ type Out : DerefMut < Target = QueueState > ;
448428}
449429
450430/// Trait to access and manipulate a virtio queue.
451431///
452432/// To optimize for performance, different implementations of the `QueueStateT` trait may be
453433/// provided for single-threaded context and multi-threaded context.
454434pub trait QueueStateT {
435+ /// Lifetime-generic guard. Usually this is just `Self`, and implementors
436+ /// of `QueueStateT` also implement `QueueStateGuard`.
437+ type Guard : for < ' a > QueueStateGuard < ' a > ;
438+
455439 /// Construct an empty virtio queue state object with the given `max_size`.
456440 fn new ( max_size : u16 ) -> Self ;
457441
@@ -465,7 +449,7 @@ pub trait QueueStateT {
465449 ///
466450 /// Logically this method will acquire the underlying lock protecting the `QueueState` Object.
467451 /// The lock will be released when the returned object gets dropped.
468- fn lock ( & mut self ) -> QueueStateGuard ;
452+ fn lock ( & mut self ) -> < Self :: Guard as QueueStateGuard > :: Out ;
469453
470454 /// Get the maximum size of the virtio queue.
471455 fn max_size ( & self ) -> u16 ;
@@ -664,7 +648,13 @@ impl QueueState {
664648 }
665649}
666650
651+ impl < ' a > QueueStateGuard < ' a > for QueueState {
652+ type Out = & ' a mut QueueState ;
653+ }
654+
667655impl QueueStateT for QueueState {
656+ type Guard = Self ;
657+
668658 fn new ( max_size : u16 ) -> Self {
669659 QueueState {
670660 max_size,
@@ -751,8 +741,8 @@ impl QueueStateT for QueueState {
751741 self . event_idx_enabled = false ;
752742 }
753743
754- fn lock ( & mut self ) -> QueueStateGuard {
755- QueueStateGuard :: StateObject ( self )
744+ fn lock ( & mut self ) -> & mut Self {
745+ self
756746 }
757747
758748 fn max_size ( & self ) -> u16 {
@@ -919,7 +909,13 @@ pub struct QueueStateSync {
919909 state : Arc < Mutex < QueueState > > ,
920910}
921911
912+ impl < ' a > QueueStateGuard < ' a > for QueueStateSync {
913+ type Out = MutexGuard < ' a , QueueState > ;
914+ }
915+
922916impl QueueStateT for QueueStateSync {
917+ type Guard = Self ;
918+
923919 fn new ( max_size : u16 ) -> Self {
924920 QueueStateSync {
925921 state : Arc :: new ( Mutex :: new ( QueueState :: new ( max_size) ) ) ,
@@ -934,8 +930,8 @@ impl QueueStateT for QueueStateSync {
934930 self . state . lock ( ) . unwrap ( ) . reset ( ) ;
935931 }
936932
937- fn lock ( & mut self ) -> QueueStateGuard {
938- QueueStateGuard :: MutexGuard ( self . state . lock ( ) . unwrap ( ) )
933+ fn lock ( & mut self ) -> MutexGuard < QueueState > {
934+ self . state . lock ( ) . unwrap ( )
939935 }
940936
941937 fn max_size ( & self ) -> u16 {
@@ -1040,7 +1036,7 @@ impl<M: GuestAddressSpace, S: QueueStateT> Queue<M, S> {
10401036 ///
10411037 /// Logically this method will acquire the underlying lock protecting the `QueueState` Object.
10421038 /// The lock will be released when the returned object gets dropped.
1043- pub fn lock ( & mut self ) -> QueueStateGuard {
1039+ pub fn lock ( & mut self ) -> < S :: Guard as QueueStateGuard > :: Out {
10441040 self . state . lock ( )
10451041 }
10461042
0 commit comments