66//
77// Copyright © 2019 Intel Corporation
88//
9- // Copyright (C) 2020 Alibaba Cloud. All rights reserved.
9+ // Copyright (C) 2020-2021 Alibaba Cloud. All rights reserved.
1010//
1111// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
1212
@@ -26,7 +26,7 @@ use std::mem::size_of;
2626use std:: num:: Wrapping ;
2727use std:: ops:: { Deref , DerefMut } ;
2828use std:: sync:: atomic:: { fence, Ordering } ;
29- use std:: sync:: MutexGuard ;
29+ use std:: sync:: { Arc , Mutex , MutexGuard } ;
3030
3131use defs:: {
3232 VIRTQ_AVAIL_ELEMENT_SIZE , VIRTQ_AVAIL_RING_HEADER_SIZE , VIRTQ_AVAIL_RING_META_SIZE ,
@@ -849,6 +849,97 @@ impl<M: GuestAddressSpace> QueueStateT<M> for QueueState<M> {
849849 }
850850}
851851
852+ /// Struct to maintain information and manipulate state of a virtio queue for multi-threaded
853+ /// context.
854+ #[ derive( Clone , Debug ) ]
855+ pub struct QueueStateSync < M : GuestAddressSpace > {
856+ state : Arc < Mutex < QueueState < M > > > ,
857+ }
858+
859+ impl < M : GuestAddressSpace > QueueStateT < M > for QueueStateSync < M > {
860+ fn new ( max_size : u16 ) -> Self {
861+ QueueStateSync {
862+ state : Arc :: new ( Mutex :: new ( QueueState :: new ( max_size) ) ) ,
863+ }
864+ }
865+
866+ fn lock ( & mut self ) -> QueueStateGuard < ' _ , M > {
867+ QueueStateGuard :: MutexGuard ( self . state . lock ( ) . unwrap ( ) )
868+ }
869+
870+ fn max_size ( & self ) -> u16 {
871+ self . state . lock ( ) . unwrap ( ) . max_size ( )
872+ }
873+
874+ fn actual_size ( & self ) -> u16 {
875+ self . state . lock ( ) . unwrap ( ) . actual_size ( )
876+ }
877+
878+ fn set_size ( & mut self , size : u16 ) {
879+ self . state . lock ( ) . unwrap ( ) . set_size ( size)
880+ }
881+
882+ fn ready ( & self ) -> bool {
883+ self . state . lock ( ) . unwrap ( ) . ready
884+ }
885+
886+ fn set_ready ( & mut self , ready : bool ) {
887+ self . state . lock ( ) . unwrap ( ) . set_ready ( ready)
888+ }
889+
890+ fn set_desc_table_address ( & mut self , low : Option < u32 > , high : Option < u32 > ) {
891+ self . state . lock ( ) . unwrap ( ) . set_desc_table_address ( low, high) ;
892+ }
893+
894+ fn set_avail_ring_address ( & mut self , low : Option < u32 > , high : Option < u32 > ) {
895+ self . state . lock ( ) . unwrap ( ) . set_avail_ring_address ( low, high) ;
896+ }
897+
898+ fn set_used_ring_address ( & mut self , low : Option < u32 > , high : Option < u32 > ) {
899+ self . state . lock ( ) . unwrap ( ) . set_used_ring_address ( low, high) ;
900+ }
901+
902+ fn reset ( & mut self ) {
903+ self . state . lock ( ) . unwrap ( ) . reset ( ) ;
904+ }
905+
906+ fn set_event_idx ( & mut self , enabled : bool ) {
907+ self . state . lock ( ) . unwrap ( ) . set_event_idx ( enabled) ;
908+ }
909+
910+ fn is_valid ( & self , mem : & M :: T ) -> bool {
911+ self . state . lock ( ) . unwrap ( ) . is_valid ( mem)
912+ }
913+
914+ fn avail_idx ( & self , mem : & M :: T , order : Ordering ) -> Result < Wrapping < u16 > , Error > {
915+ self . state . lock ( ) . unwrap ( ) . avail_idx ( mem, order)
916+ }
917+
918+ fn add_used ( & mut self , mem : & M :: T , head_index : u16 , len : u32 ) -> Result < ( ) , Error > {
919+ self . state . lock ( ) . unwrap ( ) . add_used ( mem, head_index, len)
920+ }
921+
922+ fn enable_notification ( & mut self , mem : & M :: T ) -> Result < bool , Error > {
923+ self . state . lock ( ) . unwrap ( ) . enable_notification ( mem)
924+ }
925+
926+ fn disable_notification ( & mut self , mem : & M :: T ) -> Result < ( ) , Error > {
927+ self . state . lock ( ) . unwrap ( ) . disable_notification ( mem)
928+ }
929+
930+ fn needs_notification ( & mut self , mem : & M :: T ) -> Result < bool , Error > {
931+ self . state . lock ( ) . unwrap ( ) . needs_notification ( mem)
932+ }
933+
934+ fn next_avail ( & self ) -> u16 {
935+ self . state . lock ( ) . unwrap ( ) . next_avail ( )
936+ }
937+
938+ fn set_next_avail ( & mut self , next_avail : u16 ) {
939+ self . state . lock ( ) . unwrap ( ) . set_next_avail ( next_avail) ;
940+ }
941+ }
942+
852943/// A convenient wrapper struct for a virtio queue, with associated GuestMemory object.
853944#[ derive( Clone , Debug ) ]
854945pub struct Queue < M : GuestAddressSpace , S : QueueStateT < M > = QueueState < M > > {
0 commit comments