1 use std::{ 2 collections::VecDeque, 3 fmt::Debug, 4 sync::{Arc, Mutex, Weak}, 5 task::Wake, 6 }; 7 8 use log::error; 9 10 use crate::device::queue::{ 11 GetCaptureBufferByIndex, GetFreeBufferError, GetFreeCaptureBuffer, TryGetBufferError, 12 }; 13 use crate::{ 14 bindings, 15 device::poller::Waker, 16 memory::{BufferHandles, MmapHandle, PrimitiveBufferHandles}, 17 Format, 18 }; 19 20 use thiserror::Error; 21 22 #[derive(Debug, Error)] 23 pub enum GetSuitableBufferError { 24 #[error("error while calling try_get_free_buffer(): {0}")] 25 TryGetFree(#[from] GetFreeBufferError), 26 #[error("error while calling try_get_buffer(): {0}")] 27 TryGetIndexed(#[from] TryGetBufferError), 28 } 29 30 pub trait HandlesProvider: Send + 'static { 31 type HandleType: BufferHandles; 32 33 /// Request a set of handles. Returns `None` if no handle is currently 34 /// available. If that is the case, `waker` will be signaled when handles 35 /// are available again. get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType>36 fn get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType>; 37 get_suitable_buffer_for<'a, Q>( &self, _handles: &Self::HandleType, queue: &'a Q, ) -> Result<Q::Queueable, GetSuitableBufferError> where Q: GetCaptureBufferByIndex<'a, Self::HandleType> + GetFreeCaptureBuffer<'a, Self::HandleType>,38 fn get_suitable_buffer_for<'a, Q>( 39 &self, 40 _handles: &Self::HandleType, 41 queue: &'a Q, 42 ) -> Result<Q::Queueable, GetSuitableBufferError> 43 where 44 Q: GetCaptureBufferByIndex<'a, Self::HandleType> 45 + GetFreeCaptureBuffer<'a, Self::HandleType>, 46 { 47 Ok(queue.try_get_free_buffer()?) 48 } 49 } 50 51 /// `HandleProvider`s on the heap are `HandleProvider`s too. 52 impl<P: HandlesProvider> HandlesProvider for Box<P> { 53 type HandleType = P::HandleType; 54 get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType>55 fn get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType> { 56 self.as_ref().get_handles(waker) 57 } 58 get_suitable_buffer_for<'a, Q>( &self, handles: &Self::HandleType, queue: &'a Q, ) -> Result<Q::Queueable, GetSuitableBufferError> where Q: GetCaptureBufferByIndex<'a, Self::HandleType> + GetFreeCaptureBuffer<'a, Self::HandleType>,59 fn get_suitable_buffer_for<'a, Q>( 60 &self, 61 handles: &Self::HandleType, 62 queue: &'a Q, 63 ) -> Result<Q::Queueable, GetSuitableBufferError> 64 where 65 Q: GetCaptureBufferByIndex<'a, Self::HandleType> 66 + GetFreeCaptureBuffer<'a, Self::HandleType>, 67 { 68 self.as_ref().get_suitable_buffer_for(handles, queue) 69 } 70 } 71 72 impl<P: HandlesProvider + Sync> HandlesProvider for Arc<P> { 73 type HandleType = P::HandleType; 74 get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType>75 fn get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType> { 76 self.as_ref().get_handles(waker) 77 } 78 get_suitable_buffer_for<'a, Q>( &self, handles: &Self::HandleType, queue: &'a Q, ) -> Result<Q::Queueable, GetSuitableBufferError> where Q: GetCaptureBufferByIndex<'a, Self::HandleType> + GetFreeCaptureBuffer<'a, Self::HandleType>,79 fn get_suitable_buffer_for<'a, Q>( 80 &self, 81 handles: &Self::HandleType, 82 queue: &'a Q, 83 ) -> Result<Q::Queueable, GetSuitableBufferError> 84 where 85 Q: GetCaptureBufferByIndex<'a, Self::HandleType> 86 + GetFreeCaptureBuffer<'a, Self::HandleType>, 87 { 88 self.as_ref().get_suitable_buffer_for(handles, queue) 89 } 90 } 91 92 pub struct MmapProvider(Vec<MmapHandle>); 93 94 impl MmapProvider { new(format: &Format) -> Self95 pub fn new(format: &Format) -> Self { 96 Self(vec![Default::default(); format.plane_fmt.len()]) 97 } 98 } 99 100 impl HandlesProvider for MmapProvider { 101 type HandleType = Vec<MmapHandle>; 102 get_handles(&self, _waker: &Arc<Waker>) -> Option<Self::HandleType>103 fn get_handles(&self, _waker: &Arc<Waker>) -> Option<Self::HandleType> { 104 Some(self.0.clone()) 105 } 106 } 107 108 /// Internals of `PooledHandlesProvider`, which acts just as a protected wrapper 109 /// around this structure. 110 struct PooledHandlesProviderInternal<H: BufferHandles> { 111 buffers: VecDeque<H>, 112 waker: Option<Arc<Waker>>, 113 } 114 115 unsafe impl<H: BufferHandles> Send for PooledHandlesProviderInternal<H> {} 116 117 /// A handles provider that recycles buffers from a fixed set in a pool. 118 /// Provided `PooledHandles` will not be recycled for as long as the instance is 119 /// alive. Once it is dropped, it the underlying buffer returns into the pool to 120 /// be reused later. 121 pub struct PooledHandlesProvider<H: BufferHandles> { 122 d: Arc<Mutex<PooledHandlesProviderInternal<H>>>, 123 } 124 125 impl<H: BufferHandles> PooledHandlesProvider<H> { 126 /// Create a new `PooledMemoryProvider`, using the set in `buffers`. new<B: IntoIterator<Item = H>>(buffers: B) -> Self127 pub fn new<B: IntoIterator<Item = H>>(buffers: B) -> Self { 128 Self { 129 d: Arc::new(Mutex::new(PooledHandlesProviderInternal { 130 buffers: buffers.into_iter().collect(), 131 waker: None, 132 })), 133 } 134 } 135 } 136 137 impl<H: BufferHandles> HandlesProvider for PooledHandlesProvider<H> { 138 type HandleType = PooledHandles<H>; 139 get_handles(&self, waker: &Arc<Waker>) -> Option<PooledHandles<H>>140 fn get_handles(&self, waker: &Arc<Waker>) -> Option<PooledHandles<H>> { 141 let mut d = self.d.lock().unwrap(); 142 match d.buffers.pop_front() { 143 Some(handles) => Some(PooledHandles::new(&self.d, handles)), 144 None => { 145 d.waker = Some(Arc::clone(waker)); 146 None 147 } 148 } 149 } 150 } 151 152 /// A set of buffer handles provided by `PooledHandlesProvider`. The handles 153 /// will remain out of the pool as long as this instance is alive, i.e. the 154 /// handles will be recycled when it is dropped. 155 pub struct PooledHandles<H: BufferHandles> { 156 // Use of Option is necessary here because of Drop implementation, but the 157 // Option will always be Some() 158 handles: Option<H>, 159 provider: Weak<Mutex<PooledHandlesProviderInternal<H>>>, 160 } 161 162 impl<H: BufferHandles> PooledHandles<H> { new(provider: &Arc<Mutex<PooledHandlesProviderInternal<H>>>, handles: H) -> Self163 fn new(provider: &Arc<Mutex<PooledHandlesProviderInternal<H>>>, handles: H) -> Self { 164 Self { 165 handles: Some(handles), 166 provider: Arc::downgrade(provider), 167 } 168 } 169 handles(&self) -> &H170 pub fn handles(&self) -> &H { 171 self.handles.as_ref().unwrap() 172 } 173 } 174 175 impl<H: BufferHandles + Debug> Debug for PooledHandles<H> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result176 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 177 self.handles.fmt(f) 178 } 179 } 180 181 impl<H: BufferHandles> Drop for PooledHandles<H> { 182 /// Return the handles to the pool if it still exists, otherwise the handles 183 /// themselves are destroyed. drop(&mut self)184 fn drop(&mut self) { 185 match self.provider.upgrade() { 186 None => (), 187 Some(provider) => { 188 let mut provider = provider.lock().unwrap(); 189 provider.buffers.push_back(self.handles.take().unwrap()); 190 if let Some(waker) = provider.waker.take() { 191 waker.wake(); 192 } 193 } 194 } 195 } 196 } 197 198 impl<H: BufferHandles> BufferHandles for PooledHandles<H> { 199 type SupportedMemoryType = H::SupportedMemoryType; 200 len(&self) -> usize201 fn len(&self) -> usize { 202 self.handles.as_ref().unwrap().len() 203 } 204 fill_v4l2_plane(&self, index: usize, plane: &mut bindings::v4l2_plane)205 fn fill_v4l2_plane(&self, index: usize, plane: &mut bindings::v4l2_plane) { 206 self.handles.as_ref().unwrap().fill_v4l2_plane(index, plane); 207 } 208 } 209 210 impl<H: PrimitiveBufferHandles> PrimitiveBufferHandles for PooledHandles<H> { 211 type HandleType = H::HandleType; 212 const MEMORY_TYPE: Self::SupportedMemoryType = H::MEMORY_TYPE; 213 } 214