From 0792fe4f1affd16ae28158022fc4eb80964067d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 13 Dec 2018 17:11:48 +0200 Subject: [PATCH] ts-appsrc: Fix deadlock during shutdown The IO Context has to be alive longer than the other parts of the state. Otherwise a deadlock can happen between shutting down the IO context (thread join while the state lock is held) and stuff happening on the IO context (which might take the state lock). --- gst-plugin-threadshare/src/appsrc.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/gst-plugin-threadshare/src/appsrc.rs b/gst-plugin-threadshare/src/appsrc.rs index 32e4e973..083a35a2 100644 --- a/gst-plugin-threadshare/src/appsrc.rs +++ b/gst-plugin-threadshare/src/appsrc.rs @@ -418,15 +418,25 @@ impl AppSrc { fn unprepare(&self, element: &gst::Element) -> Result<(), ()> { gst_debug!(self.cat, obj: element, "Unpreparing"); - let mut state = self.state.lock().unwrap(); + // FIXME: The IO Context has to be alive longer than the other parts + // of the state. Otherwise a deadlock can happen between shutting down + // the IO context (thread join while the state lock is held) and stuff + // happening on the IO context (which might take the state lock). + let io_context = { + let mut state = self.state.lock().unwrap(); - if let (&Some(ref pending_future_id), &Some(ref io_context)) = - (&state.pending_future_id, &state.io_context) - { - io_context.release_pending_future_id(*pending_future_id); - } + if let (&Some(ref pending_future_id), &Some(ref io_context)) = + (&state.pending_future_id, &state.io_context) + { + io_context.release_pending_future_id(*pending_future_id); + } - *state = State::default(); + let io_context = state.io_context.take(); + *state = State::default(); + io_context + }; + + drop(io_context); gst_debug!(self.cat, obj: element, "Unprepared");