diff options
author | François Laignel <francois@centricular.com> | 2023-05-26 15:23:03 +0300 |
---|---|---|
committer | François Laignel <francois@centricular.com> | 2023-05-26 15:23:03 +0300 |
commit | 4cc2498c24b91d16a1075ec330b61b52bd9c3b72 (patch) | |
tree | 34472a4e11b6e3bc195d69cab7bfa88519448e86 /net | |
parent | a20855dfd9a8dae62b473c1f9210e755881b4108 (diff) |
webrtcsink: use spawn_blocking instead of call_async
In `webrtcsink`, we terminate a session by setting the session's pipeline to
`Null` like this:
```rust
pipeline.call_async(|pipeline| {
[...]
pipeline.set_state(gst::State::Null);
[...]
// the following cvar is awaited in unprepare()
cvar.notify_one();
});
```
However, `pipeline.call_async` keeps a ref on the pipeline until it's done,
which means the `cvar` is notified before `pipeline` is actually 'disposed',
which happens in a different thread than `unprepare`'s. [`gst_rtp_bin_dispose`]
releases some resources when the pipeline is unrefed. In some cases, those
resources are actually released after the main thread has returned, leading
various issues.
This commit uses tokio runtime's `spawn_blocking` instead, which allows owning
and disposing of the pipeline before the `cvar` is notified.
[`gst_rtp_bin_dispose`]: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpbin.c#L3108
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1225>
Diffstat (limited to 'net')
-rw-r--r-- | net/webrtc/src/webrtcsink/imp.rs | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/net/webrtc/src/webrtcsink/imp.rs b/net/webrtc/src/webrtcsink/imp.rs index 3427724e..4c58ec6a 100644 --- a/net/webrtc/src/webrtcsink/imp.rs +++ b/net/webrtc/src/webrtcsink/imp.rs @@ -799,13 +799,15 @@ impl State { let (sessions, _cvar) = &*finalizing_sessions; sessions.lock().unwrap().insert(session_id.clone()); - session.pipeline.call_async(move |pipeline| { + let pipeline = session.pipeline.clone(); + RUNTIME.spawn_blocking(move || { if let Some(stats_collection_handle) = stats_collection_handle { stats_collection_handle.abort(); let _ = RUNTIME.block_on(stats_collection_handle); } let _ = pipeline.set_state(gst::State::Null); + drop(pipeline); let (sessions, cvar) = &*finalizing_sessions; let mut sessions = sessions.lock().unwrap(); |