@@ -1013,6 +1013,35 @@ pub struct Queue<M: GuestAddressSpace, S: QueueStateT = QueueState> {
1013
1013
pub state : S ,
1014
1014
}
1015
1015
1016
+ /// A struct that holds an exclusive reference to a `QueueState` object, that was
1017
+ /// obtained from a `Queue`. As such it remembers the associated GuestMemory object
1018
+ /// and can use it to return an iterator.
1019
+ pub struct QueueGuard < M : GuestAddressSpace , G : DerefMut < Target = QueueState > > {
1020
+ mem : M :: T ,
1021
+ guard : G ,
1022
+ }
1023
+
1024
+ impl < M : GuestAddressSpace , G : DerefMut < Target = QueueState > > Deref for QueueGuard < M , G > {
1025
+ type Target = QueueState ;
1026
+
1027
+ fn deref ( & self ) -> & Self :: Target {
1028
+ self . guard . deref ( )
1029
+ }
1030
+ }
1031
+
1032
+ impl < M : GuestAddressSpace , G : DerefMut < Target = QueueState > > DerefMut for QueueGuard < M , G > {
1033
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
1034
+ self . guard . deref_mut ( )
1035
+ }
1036
+ }
1037
+
1038
+ impl < M : GuestAddressSpace , G : DerefMut < Target = QueueState > > QueueGuard < M , G > {
1039
+ /// A consuming iterator over all available descriptor chain heads offered by the driver.
1040
+ pub fn iter ( & mut self ) -> Result < AvailIter < ' _ , M :: T > , Error > {
1041
+ self . guard . iter ( self . mem . clone ( ) )
1042
+ }
1043
+ }
1044
+
1016
1045
impl < M : GuestAddressSpace , S : QueueStateT > Queue < M , S > {
1017
1046
/// Construct an empty virtio queue with the given `max_size`.
1018
1047
pub fn new ( mem : M , max_size : u16 ) -> Self {
@@ -1036,8 +1065,11 @@ impl<M: GuestAddressSpace, S: QueueStateT> Queue<M, S> {
1036
1065
///
1037
1066
/// Logically this method will acquire the underlying lock protecting the `QueueState` Object.
1038
1067
/// The lock will be released when the returned object gets dropped.
1039
- pub fn lock ( & mut self ) -> <S :: Guard as QueueStateGuard >:: Out {
1040
- self . state . lock ( )
1068
+ pub fn lock ( & mut self ) -> QueueGuard < M , <S :: Guard as QueueStateGuard >:: Out > {
1069
+ QueueGuard {
1070
+ mem : self . mem . memory ( ) ,
1071
+ guard : self . state . lock ( ) ,
1072
+ }
1041
1073
}
1042
1074
1043
1075
/// Get the maximum size of the virtio queue.
0 commit comments