mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-30 07:20:59 +00:00
threadshare: Make sure to shutdown sockets/queues without any mutexes locked
And make sure that the IOContext stays alive until they are fully done.
This commit is contained in:
parent
b4d1145490
commit
6ebc8988b2
3 changed files with 74 additions and 33 deletions
|
@ -426,7 +426,13 @@ impl ProxySink {
|
||||||
"Trying to empty pending queue"
|
"Trying to empty pending queue"
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut queue = state.queue.as_ref().unwrap().0.lock().unwrap();
|
let mut queue = match state.queue {
|
||||||
|
Some(ref queue) => queue.0.lock().unwrap(),
|
||||||
|
None => {
|
||||||
|
return Ok(Async::Ready(()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let SharedQueueInner {
|
let SharedQueueInner {
|
||||||
ref mut pending_queue,
|
ref mut pending_queue,
|
||||||
ref queue,
|
ref queue,
|
||||||
|
@ -1161,14 +1167,10 @@ impl ProxySrc {
|
||||||
fn unprepare(&self, element: &Element) -> Result<(), ()> {
|
fn unprepare(&self, element: &Element) -> Result<(), ()> {
|
||||||
gst_debug!(self.cat, obj: element, "Unpreparing");
|
gst_debug!(self.cat, obj: element, "Unpreparing");
|
||||||
|
|
||||||
|
// FIXME: The IO Context has to be alive longer than the queue,
|
||||||
|
// otherwise the queue can't finish any remaining work
|
||||||
|
let (mut queue, io_context) = {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
if let Some(ref queue) = state.queue {
|
|
||||||
let queue = queue.0.lock().unwrap();
|
|
||||||
|
|
||||||
if let Some(ref queue) = queue.queue {
|
|
||||||
queue.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (&Some(ref pending_future_id), &Some(ref io_context)) =
|
if let (&Some(ref pending_future_id), &Some(ref io_context)) =
|
||||||
(&state.pending_future_id, &state.io_context)
|
(&state.pending_future_id, &state.io_context)
|
||||||
|
@ -1176,9 +1178,27 @@ impl ProxySrc {
|
||||||
io_context.release_pending_future_id(*pending_future_id);
|
io_context.release_pending_future_id(*pending_future_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue = if let Some(ref queue) = state.queue.take() {
|
||||||
|
let mut queue = queue.0.lock().unwrap();
|
||||||
|
queue.queue.take()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let io_context = state.io_context.take();
|
||||||
|
|
||||||
*state = StateSrc::default();
|
*state = StateSrc::default();
|
||||||
|
|
||||||
|
(queue, io_context)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(ref queue) = queue.take() {
|
||||||
|
queue.shutdown();
|
||||||
|
}
|
||||||
|
drop(io_context);
|
||||||
|
|
||||||
gst_debug!(self.cat, obj: element, "Unprepared");
|
gst_debug!(self.cat, obj: element, "Unprepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -329,6 +329,10 @@ impl Queue {
|
||||||
..
|
..
|
||||||
} = *state;
|
} = *state;
|
||||||
|
|
||||||
|
if dq.is_none() {
|
||||||
|
return Ok(Async::Ready(()));
|
||||||
|
}
|
||||||
|
|
||||||
gst_log!(
|
gst_log!(
|
||||||
queue.cat,
|
queue.cat,
|
||||||
obj: &element_clone,
|
obj: &element_clone,
|
||||||
|
@ -779,20 +783,29 @@ impl Queue {
|
||||||
fn unprepare(&self, element: &Element) -> Result<(), ()> {
|
fn unprepare(&self, element: &Element) -> Result<(), ()> {
|
||||||
gst_debug!(self.cat, obj: element, "Unpreparing");
|
gst_debug!(self.cat, obj: element, "Unpreparing");
|
||||||
|
|
||||||
|
// FIXME: The IO Context has to be alive longer than the queue,
|
||||||
|
// otherwise the queue can't finish any remaining work
|
||||||
|
let (mut queue, io_context) = {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
if let Some(ref queue) = state.queue {
|
|
||||||
queue.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (&Some(ref pending_future_id), &Some(ref io_context)) =
|
if let (&Some(ref pending_future_id), &Some(ref io_context)) =
|
||||||
(&state.pending_future_id, &state.io_context)
|
(&state.pending_future_id, &state.io_context)
|
||||||
{
|
{
|
||||||
io_context.release_pending_future_id(*pending_future_id);
|
io_context.release_pending_future_id(*pending_future_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue = state.queue.take();
|
||||||
|
let io_context = state.io_context.take();
|
||||||
|
|
||||||
*state = State::default();
|
*state = State::default();
|
||||||
|
|
||||||
|
(queue, io_context)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(ref queue) = queue.take() {
|
||||||
|
queue.shutdown();
|
||||||
|
}
|
||||||
|
drop(io_context);
|
||||||
|
|
||||||
gst_debug!(self.cat, obj: element, "Unprepared");
|
gst_debug!(self.cat, obj: element, "Unprepared");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -607,19 +607,27 @@ impl UdpSrc {
|
||||||
fn unprepare(&self, element: &Element) -> Result<(), ()> {
|
fn unprepare(&self, element: &Element) -> Result<(), ()> {
|
||||||
gst_debug!(self.cat, obj: element, "Unpreparing");
|
gst_debug!(self.cat, obj: element, "Unpreparing");
|
||||||
|
|
||||||
|
// FIXME: The IO Context has to be alive longer than the queue,
|
||||||
|
// otherwise the queue can't finish any remaining work
|
||||||
|
let (mut socket, io_context) = {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
if let Some(ref socket) = state.socket {
|
|
||||||
socket.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (&Some(ref pending_future_id), &Some(ref io_context)) =
|
if let (&Some(ref pending_future_id), &Some(ref io_context)) =
|
||||||
(&state.pending_future_id, &state.io_context)
|
(&state.pending_future_id, &state.io_context)
|
||||||
{
|
{
|
||||||
io_context.release_pending_future_id(*pending_future_id);
|
io_context.release_pending_future_id(*pending_future_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let socket = state.socket.take();
|
||||||
|
let io_context = state.io_context.take();
|
||||||
*state = State::default();
|
*state = State::default();
|
||||||
|
(socket, io_context)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(ref socket) = socket.take() {
|
||||||
|
socket.shutdown();
|
||||||
|
}
|
||||||
|
drop(io_context);
|
||||||
|
|
||||||
gst_debug!(self.cat, obj: element, "Unprepared");
|
gst_debug!(self.cat, obj: element, "Unprepared");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue