@@ -470,29 +470,30 @@ impl AudioContext {
470470 ///
471471 /// * The audio device is not available
472472 /// * For a `BackendSpecificError`
473- #[ allow( clippy:: await_holding_lock) ] // false positive due to explicit drop
474473 pub async fn resume ( & self ) {
475- // Lock the backend manager mutex to avoid concurrent calls
476- log:: debug!( "Resume called, locking backend manager" ) ;
477- let backend_manager_guard = self . backend_manager . lock ( ) . unwrap ( ) ;
474+ let ( sender, receiver) = oneshot:: channel ( ) ;
478475
479- if self . state ( ) != AudioContextState :: Suspended {
480- log :: debug! ( "Resume no-op - context is not suspended" ) ;
481- return ;
482- }
476+ {
477+ // Lock the backend manager mutex to avoid concurrent calls
478+ log :: debug! ( "Resume called, locking backend manager" ) ;
479+ let backend_manager_guard = self . backend_manager . lock ( ) . unwrap ( ) ;
483480
484- // Ask the audio host to resume the stream
485- backend_manager_guard. resume ( ) ;
481+ if self . state ( ) != AudioContextState :: Suspended {
482+ log:: debug!( "Resume no-op - context is not suspended" ) ;
483+ return ;
484+ }
486485
487- // Then, ask to resume rendering via a control message
488- log:: debug!( "Resumed audio stream, waking audio graph" ) ;
489- let ( sender, receiver) = oneshot:: channel ( ) ;
490- let notify = OneshotNotify :: Async ( sender) ;
491- self . base
492- . send_control_msg ( ControlMessage :: Resume { notify } ) ;
486+ // Ask the audio host to resume the stream
487+ backend_manager_guard. resume ( ) ;
493488
494- // Drop the Mutex guard so we won't hold it across an await
495- drop ( backend_manager_guard) ;
489+ // Then, ask to resume rendering via a control message
490+ log:: debug!( "Resumed audio stream, waking audio graph" ) ;
491+ let notify = OneshotNotify :: Async ( sender) ;
492+ self . base
493+ . send_control_msg ( ControlMessage :: Resume { notify } ) ;
494+
495+ // Drop the Mutex guard so we won't hold it across an await point
496+ }
496497
497498 // Wait for the render thread to have processed the resume message
498499 // The AudioContextState will be updated by the render thread.
@@ -767,4 +768,19 @@ mod tests {
767768 let time5 = context. current_time ( ) ;
768769 assert_eq ! ( time5, time4) ; // no progression of time
769770 }
771+
772+ fn require_send_sync < T : Send + Sync > ( _: T ) { }
773+
774+ #[ test]
775+ fn test_all_futures_thread_safe ( ) {
776+ let options = AudioContextOptions {
777+ sink_id : "none" . into ( ) ,
778+ ..AudioContextOptions :: default ( )
779+ } ;
780+ let context = AudioContext :: new ( options) ;
781+
782+ require_send_sync ( context. suspend ( ) ) ;
783+ require_send_sync ( context. resume ( ) ) ;
784+ require_send_sync ( context. close ( ) ) ;
785+ }
770786}
0 commit comments