@@ -170,6 +170,41 @@ struct DeviceHandles {
170170 capture : Option < alsa:: PCM > ,
171171}
172172
173+ impl DeviceHandles {
174+ fn handle_mut ( & mut self , stream_type : alsa:: Direction ) -> & mut Option < alsa:: PCM > {
175+ match stream_type {
176+ alsa:: Direction :: Playback => & mut self . playback ,
177+ alsa:: Direction :: Capture => & mut self . capture ,
178+ }
179+ }
180+
181+ /// Get a mutable reference to the `alsa::PCM` handle for a specific `stream_type`.
182+ /// If the handle is not yet opened, it will be opened and stored in `self`.
183+ fn get_mut (
184+ & mut self ,
185+ name : & str ,
186+ stream_type : alsa:: Direction ,
187+ ) -> Result < & mut alsa:: PCM , alsa:: Error > {
188+ let pcm = self . handle_mut ( stream_type) ;
189+ match pcm {
190+ Some ( pcm) => Ok ( pcm) ,
191+ None => {
192+ * pcm = Some ( alsa:: pcm:: PCM :: new ( name, stream_type, true ) ?) ;
193+ Ok ( pcm. as_mut ( ) . unwrap ( ) )
194+ }
195+ }
196+ }
197+
198+ /// Take ownership of the `alsa::PCM` handle for a specific `stream_type`.
199+ /// If the handle is not yet opened, it will be opened and returned.
200+ fn take ( & mut self , name : & str , stream_type : alsa:: Direction ) -> Result < alsa:: PCM , alsa:: Error > {
201+ match self . handle_mut ( stream_type) . take ( ) {
202+ Some ( pcm) => Ok ( pcm) ,
203+ None => Ok ( alsa:: pcm:: PCM :: new ( name, stream_type, true ) ?) ,
204+ }
205+ }
206+ }
207+
173208pub struct Device {
174209 name : String ,
175210 handles : Mutex < DeviceHandles > ,
@@ -182,19 +217,11 @@ impl Device {
182217 sample_format : SampleFormat ,
183218 stream_type : alsa:: Direction ,
184219 ) -> Result < StreamInner , BuildStreamError > {
185- let name = & self . name ;
186-
187- let device_handle = {
188- let mut guard = self . handles . lock ( ) ;
189- match stream_type {
190- alsa:: Direction :: Playback => guard. playback . take ( ) ,
191- alsa:: Direction :: Capture => guard. capture . take ( ) ,
192- }
193- } ;
194-
195- let handle_result = Ok ( device_handle) . transpose ( ) . unwrap_or_else ( || {
196- alsa:: pcm:: PCM :: new ( name, stream_type, true ) . map_err ( |e| ( e, e. errno ( ) ) )
197- } ) ;
220+ let handle_result = self
221+ . handles
222+ . lock ( )
223+ . take ( & self . name , stream_type)
224+ . map_err ( |e| ( e, e. errno ( ) ) ) ;
198225
199226 let handle = match handle_result {
200227 Err ( ( _, Some ( nix:: errno:: Errno :: EBUSY ) ) ) => {
@@ -256,24 +283,10 @@ impl Device {
256283 & self ,
257284 stream_t : alsa:: Direction ,
258285 ) -> Result < VecIntoIter < SupportedStreamConfigRange > , SupportedStreamConfigsError > {
259- let name = & self . name ;
260-
261286 let mut guard = self . handles . lock ( ) ;
262-
263- let device_handle = match stream_t {
264- alsa:: Direction :: Playback => & mut guard. playback ,
265- alsa:: Direction :: Capture => & mut guard. capture ,
266- } ;
267-
268- let handle_result = match device_handle {
269- Some ( handle) => Ok ( handle) ,
270- None => alsa:: pcm:: PCM :: new ( name, stream_t, true )
271- . map ( |handle| {
272- * device_handle = Some ( handle) ;
273- device_handle. as_mut ( ) . unwrap ( )
274- } )
275- . map_err ( |e| ( e, e. errno ( ) ) ) ,
276- } ;
287+ let handle_result = guard
288+ . get_mut ( & self . name , stream_t)
289+ . map_err ( |e| ( e, e. errno ( ) ) ) ;
277290
278291 let handle = match handle_result {
279292 Err ( ( _, Some ( nix:: errno:: Errno :: ENOENT ) ) )
0 commit comments