orottier/web-audio-api-rs

AudioContext::resume not `Send` anymore?

b-ma opened this issue · 1 comments

b-ma commented

I have this error with AudioContext::resume after upgrading to 1.0.0-rc.6

error[E0277]: `std::sync::MutexGuard<'_, Box<dyn web_audio_api::io::AudioBackendManager>>` cannot be sent between threads safely
    --> src/audio_context.rs:177:13
     |
177  |       ctx.env.execute_tokio_future(
     |               ^^^^^^^^^^^^^^^^^^^^ `std::sync::MutexGuard<'_, Box<dyn web_audio_api::io::AudioBackendManager>>` cannot be sent between threads safely
178  | /         async move {
179  | |             context_clone.resume().await;
180  | |             Ok(())
181  | |         },
     | |_________- within this `{async block@src/audio_context.rs:178:9: 181:10}`
     |
     = help: within `{async block@src/audio_context.rs:178:9: 181:10}`, the trait `Send` is not implemented for `std::sync::MutexGuard<'_, Box<dyn web_audio_api::io::AudioBackendManager>>`, which is required by `{async block@src/audio_context.rs:178:9: 181:10}: Send`
     = note: required because it captures the following types: `std::sync::MutexGuard<'_, Box<dyn web_audio_api::io::AudioBackendManager>>`, `futures_channel::oneshot::Receiver<()>`
note: required because it's used within this `async` fn body
    --> src/index.crates.io-6f17d22bba15001f/web-audio-api-1.0.0-rc.6/src/context/online.rs:474:32
     |
474  |       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();
...    |
500  | |         log::debug!("Resumed audio graph");
501  | |     }
     | |_____^
     = note: required because it captures the following types: `impl Future<Output = ()>`
note: required because it's used within this `async` block
    --> src/audio_context.rs:178:9
     |
178  | /         async move {
179  | |             context_clone.resume().await;
180  | |             Ok(())
181  | |         },
     | |_________^
note: required by a bound in `napi::Env::execute_tokio_future`
    --> src/index.crates.io-6f17d22bba15001f/napi-2.16.4/src/env.rs:1075:18
     |
1072 |   pub fn execute_tokio_future<
     |          -------------------- required by a bound in this associated function
...
1075 |     F: 'static + Send + Future<Output = Result<T>>,
     |                  ^^^^ required by this bound in `Env::execute_tokio_future`

I imagine this is due to the fixes done in #499 but I can't figure out the problem

My wrapping code (which didn't change since previous version) is:

#[js_function]
fn resume(ctx: CallContext) -> Result<JsObject> {
    let js_this = ctx.this_unchecked::<JsObject>();
    let napi_context = ctx.env.unwrap::<NapiAudioContext>(&js_this)?;
    let context_clone = Arc::clone(&napi_context.0);

    ctx.env.execute_tokio_future(
        async move {
            context_clone.resume().await;
            Ok(())
        },
        |&mut env, _val| env.get_undefined(),
    )
}

Ugh, classic async Rust. Apparently we are carrying a non-Send variable across an await point in the new version. I will have a look and add regression tests for all Future return types.