Zebediah Figura : winegstreamer: Properly clean up from failure in wg_parser_connect().
Alexandre Julliard
julliard at winehq.org
Thu Sep 16 15:34:30 CDT 2021
Module: wine
Branch: master
Commit: 721b1eb2ebe5c3eaab8ac3fb1e4f4648cbee5b4d
URL: https://source.winehq.org/git/wine.git/?a=commit;h=721b1eb2ebe5c3eaab8ac3fb1e4f4648cbee5b4d
Author: Zebediah Figura <zfigura at codeweavers.com>
Date: Wed Sep 15 18:00:07 2021 -0500
winegstreamer: Properly clean up from failure in wg_parser_connect().
In particular, unset the sink_connected value, and make sure that subsequent
wg_parser_get_read_request calls don't hang.
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winegstreamer/wg_parser.c | 76 +++++++++++++++++++++++++++++-------------
1 file changed, 53 insertions(+), 23 deletions(-)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index bf5a51aeaf4..119cbffbd88 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -1034,6 +1034,30 @@ static struct wg_parser_stream *create_stream(struct wg_parser *parser)
return stream;
}
+static void free_stream(struct wg_parser_stream *stream)
+{
+ if (stream->their_src)
+ {
+ if (stream->post_sink)
+ {
+ gst_pad_unlink(stream->their_src, stream->post_sink);
+ gst_pad_unlink(stream->post_src, stream->my_sink);
+ gst_object_unref(stream->post_src);
+ gst_object_unref(stream->post_sink);
+ stream->post_src = stream->post_sink = NULL;
+ }
+ else
+ gst_pad_unlink(stream->their_src, stream->my_sink);
+ gst_object_unref(stream->their_src);
+ }
+ gst_object_unref(stream->my_sink);
+
+ pthread_cond_destroy(&stream->event_cond);
+ pthread_cond_destroy(&stream->event_empty_cond);
+
+ free(stream);
+}
+
static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
{
struct wg_parser *parser = user;
@@ -1520,14 +1544,14 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
parser->error = false;
if (!parser->init_gst(parser))
- return E_FAIL;
+ goto out;
gst_element_set_state(parser->container, GST_STATE_PAUSED);
ret = gst_element_get_state(parser->container, NULL, NULL, -1);
if (ret == GST_STATE_CHANGE_FAILURE)
{
GST_ERROR("Failed to play stream.\n");
- return E_FAIL;
+ goto out;
}
pthread_mutex_lock(&parser->mutex);
@@ -1537,7 +1561,7 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
if (parser->error)
{
pthread_mutex_unlock(&parser->mutex);
- return E_FAIL;
+ goto out;
}
for (i = 0; i < parser->stream_count; ++i)
@@ -1577,7 +1601,7 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
if (parser->error)
{
pthread_mutex_unlock(&parser->mutex);
- return E_FAIL;
+ goto out;
}
if (gst_pad_query_duration(stream->their_src, GST_FORMAT_TIME, &duration))
{
@@ -1614,30 +1638,36 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
parser->next_offset = 0;
return S_OK;
-}
-static void free_stream(struct wg_parser_stream *stream)
-{
- if (stream->their_src)
+out:
+ if (parser->container)
+ gst_element_set_state(parser->container, GST_STATE_NULL);
+ if (parser->their_sink)
{
- if (stream->post_sink)
- {
- gst_pad_unlink(stream->their_src, stream->post_sink);
- gst_pad_unlink(stream->post_src, stream->my_sink);
- gst_object_unref(stream->post_src);
- gst_object_unref(stream->post_sink);
- stream->post_src = stream->post_sink = NULL;
- }
- else
- gst_pad_unlink(stream->their_src, stream->my_sink);
- gst_object_unref(stream->their_src);
+ gst_pad_unlink(parser->my_src, parser->their_sink);
+ gst_object_unref(parser->their_sink);
+ parser->my_src = parser->their_sink = NULL;
}
- gst_object_unref(stream->my_sink);
- pthread_cond_destroy(&stream->event_cond);
- pthread_cond_destroy(&stream->event_empty_cond);
+ for (i = 0; i < parser->stream_count; ++i)
+ free_stream(parser->streams[i]);
+ parser->stream_count = 0;
+ free(parser->streams);
+ parser->streams = NULL;
- free(stream);
+ if (parser->container)
+ {
+ gst_element_set_bus(parser->container, NULL);
+ gst_object_unref(parser->container);
+ parser->container = NULL;
+ }
+
+ pthread_mutex_lock(&parser->mutex);
+ parser->sink_connected = false;
+ pthread_mutex_unlock(&parser->mutex);
+ pthread_cond_signal(&parser->read_cond);
+
+ return E_FAIL;
}
static void CDECL wg_parser_disconnect(struct wg_parser *parser)
More information about the wine-cvs
mailing list