@@ -8,13 +8,14 @@ use std::{
88 Arc , OnceLock ,
99 atomic:: { AtomicBool , AtomicUsize , Ordering } ,
1010 } ,
11+ sync:: { Condvar , Mutex } ,
1112 time:: Duration ,
1213} ;
1314
1415use futures_util:: { StreamExt , TryFutureExt , future:: IntoStream } ;
1516use hyper:: { Response , StatusCode , body:: Incoming , header:: CONTENT_RANGE } ;
1617use hyper_util:: client:: legacy:: ResponseFuture ;
17- use parking_lot :: { Condvar , Mutex } ;
18+
1819use tempfile:: NamedTempFile ;
1920use thiserror:: Error ;
2021use tokio:: sync:: { Semaphore , mpsc, oneshot} ;
@@ -27,6 +28,8 @@ use crate::range_set::{Range, RangeSet};
2728
2829pub type AudioFileResult = Result < ( ) , librespot_core:: Error > ;
2930
31+ const DOWNLOAD_STATUS_POISON_MSG : & str = "audio download status mutex should not be poisoned" ;
32+
3033#[ derive( Error , Debug ) ]
3134pub enum AudioFileError {
3235 #[ error( "other end of channel disconnected" ) ]
@@ -163,7 +166,10 @@ impl StreamLoaderController {
163166
164167 pub fn range_available ( & self , range : Range ) -> bool {
165168 if let Some ( ref shared) = self . stream_shared {
166- let download_status = shared. download_status . lock ( ) ;
169+ let download_status = shared
170+ . download_status
171+ . lock ( )
172+ . expect ( DOWNLOAD_STATUS_POISON_MSG ) ;
167173
168174 range. length
169175 <= download_status
@@ -214,19 +220,24 @@ impl StreamLoaderController {
214220 self . fetch ( range) ;
215221
216222 if let Some ( ref shared) = self . stream_shared {
217- let mut download_status = shared. download_status . lock ( ) ;
223+ let mut download_status = shared
224+ . download_status
225+ . lock ( )
226+ . expect ( DOWNLOAD_STATUS_POISON_MSG ) ;
218227 let download_timeout = AudioFetchParams :: get ( ) . download_timeout ;
219228
220229 while range. length
221230 > download_status
222231 . downloaded
223232 . contained_length_from_value ( range. start )
224233 {
225- if shared
234+ let ( new_download_status , wait_result ) = shared
226235 . cond
227- . wait_for ( & mut download_status, download_timeout)
228- . timed_out ( )
229- {
236+ . wait_timeout ( download_status, download_timeout)
237+ . expect ( DOWNLOAD_STATUS_POISON_MSG ) ;
238+
239+ download_status = new_download_status;
240+ if wait_result. timed_out ( ) {
230241 return Err ( AudioFileError :: WaitTimeout . into ( ) ) ;
231242 }
232243
@@ -558,7 +569,11 @@ impl Read for AudioFileStreaming {
558569 let mut ranges_to_request = RangeSet :: new ( ) ;
559570 ranges_to_request. add_range ( & Range :: new ( offset, length_to_request) ) ;
560571
561- let mut download_status = self . shared . download_status . lock ( ) ;
572+ let mut download_status = self
573+ . shared
574+ . download_status
575+ . lock ( )
576+ . expect ( DOWNLOAD_STATUS_POISON_MSG ) ;
562577
563578 ranges_to_request. subtract_range_set ( & download_status. downloaded ) ;
564579 ranges_to_request. subtract_range_set ( & download_status. requested ) ;
@@ -571,12 +586,14 @@ impl Read for AudioFileStreaming {
571586
572587 let download_timeout = AudioFetchParams :: get ( ) . download_timeout ;
573588 while !download_status. downloaded . contains ( offset) {
574- if self
589+ let ( new_download_status , wait_result ) = self
575590 . shared
576591 . cond
577- . wait_for ( & mut download_status, download_timeout)
578- . timed_out ( )
579- {
592+ . wait_timeout ( download_status, download_timeout)
593+ . expect ( DOWNLOAD_STATUS_POISON_MSG ) ;
594+
595+ download_status = new_download_status;
596+ if wait_result. timed_out ( ) {
580597 return Err ( io:: Error :: new (
581598 io:: ErrorKind :: TimedOut ,
582599 Error :: deadline_exceeded ( AudioFileError :: WaitTimeout ) ,
@@ -619,6 +636,7 @@ impl Seek for AudioFileStreaming {
619636 . shared
620637 . download_status
621638 . lock ( )
639+ . expect ( DOWNLOAD_STATUS_POISON_MSG )
622640 . downloaded
623641 . contains ( requested_pos as usize ) ;
624642
0 commit comments