mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 04:56:24 +00:00
parsebin: Don't let thread run after unref
We have a dedicated one-shot thread to handle cleanup of old groups. While this is a good idea. It's an even better idea to make sure that thread is *completed* before the parsebin element to which it is related isn't freed/gone. * There can only be one cleanup thread happening at any point in time. If there is already one, we wait for the previous one to finish. * When shutting down (NULL=>READY) make sure the thread is finished https://bugzilla.gnome.org/show_bug.cgi?id=790007
This commit is contained in:
parent
43b9bcbddb
commit
35a8d42724
1 changed files with 30 additions and 2 deletions
|
@ -179,6 +179,13 @@ struct _GstParseBin
|
||||||
|
|
||||||
GList *filtered; /* elements for which error messages are filtered */
|
GList *filtered; /* elements for which error messages are filtered */
|
||||||
GList *filtered_errors; /* filtered error messages */
|
GList *filtered_errors; /* filtered error messages */
|
||||||
|
|
||||||
|
GMutex cleanup_lock; /* Mutex used to protect the cleanup thread */
|
||||||
|
GThread *cleanup_thread; /* thread used to free chains asynchronously.
|
||||||
|
* We store it to make sure we end up joining it
|
||||||
|
* before stopping the element.
|
||||||
|
* Protected by the object lock */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstParseBinClass
|
struct _GstParseBinClass
|
||||||
|
@ -939,6 +946,9 @@ gst_parse_bin_init (GstParseBin * parse_bin)
|
||||||
parse_bin->expose_allstreams = DEFAULT_EXPOSE_ALL_STREAMS;
|
parse_bin->expose_allstreams = DEFAULT_EXPOSE_ALL_STREAMS;
|
||||||
parse_bin->connection_speed = DEFAULT_CONNECTION_SPEED;
|
parse_bin->connection_speed = DEFAULT_CONNECTION_SPEED;
|
||||||
|
|
||||||
|
g_mutex_init (&parse_bin->cleanup_lock);
|
||||||
|
parse_bin->cleanup_thread = NULL;
|
||||||
|
|
||||||
GST_OBJECT_FLAG_SET (parse_bin, GST_BIN_FLAG_STREAMS_AWARE);
|
GST_OBJECT_FLAG_SET (parse_bin, GST_BIN_FLAG_STREAMS_AWARE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,6 +987,7 @@ gst_parse_bin_finalize (GObject * object)
|
||||||
g_mutex_clear (&parse_bin->dyn_lock);
|
g_mutex_clear (&parse_bin->dyn_lock);
|
||||||
g_mutex_clear (&parse_bin->subtitle_lock);
|
g_mutex_clear (&parse_bin->subtitle_lock);
|
||||||
g_mutex_clear (&parse_bin->factories_lock);
|
g_mutex_clear (&parse_bin->factories_lock);
|
||||||
|
g_mutex_clear (&parse_bin->cleanup_lock);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -2946,11 +2957,19 @@ gst_parse_chain_start_free_hidden_groups_thread (GstParseChain * chain)
|
||||||
GThread *thread;
|
GThread *thread;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GList *old_groups;
|
GList *old_groups;
|
||||||
|
GstParseBin *parsebin = chain->parsebin;
|
||||||
|
|
||||||
old_groups = chain->old_groups;
|
old_groups = chain->old_groups;
|
||||||
if (!old_groups)
|
if (!old_groups)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* If we already have a thread running, wait for it to finish */
|
||||||
|
g_mutex_lock (&parsebin->cleanup_lock);
|
||||||
|
if (parsebin->cleanup_thread) {
|
||||||
|
g_thread_join (parsebin->cleanup_thread);
|
||||||
|
parsebin->cleanup_thread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
chain->old_groups = NULL;
|
chain->old_groups = NULL;
|
||||||
thread = g_thread_try_new ("free-hidden-groups",
|
thread = g_thread_try_new ("free-hidden-groups",
|
||||||
(GThreadFunc) gst_parse_chain_free_hidden_groups, old_groups, &error);
|
(GThreadFunc) gst_parse_chain_free_hidden_groups, old_groups, &error);
|
||||||
|
@ -2959,11 +2978,14 @@ gst_parse_chain_start_free_hidden_groups_thread (GstParseChain * chain)
|
||||||
error ? error->message : "unknown reason");
|
error ? error->message : "unknown reason");
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
chain->old_groups = old_groups;
|
chain->old_groups = old_groups;
|
||||||
|
g_mutex_unlock (&parsebin->cleanup_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parsebin->cleanup_thread = thread;
|
||||||
|
g_mutex_unlock (&parsebin->cleanup_lock);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (chain->parsebin, "Started free-hidden-groups thread");
|
GST_DEBUG_OBJECT (chain->parsebin, "Started free-hidden-groups thread");
|
||||||
/* We do not need to wait for it or get any results from it */
|
|
||||||
g_thread_unref (thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gst_parse_group_new:
|
/* gst_parse_group_new:
|
||||||
|
@ -4349,6 +4371,12 @@ gst_parse_bin_change_state (GstElement * element, GstStateChange transition)
|
||||||
gst_parse_chain_free (chain_to_free);
|
gst_parse_chain_free (chain_to_free);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
|
g_mutex_lock (&parsebin->cleanup_lock);
|
||||||
|
if (parsebin->cleanup_thread) {
|
||||||
|
g_thread_join (parsebin->cleanup_thread);
|
||||||
|
parsebin->cleanup_thread = NULL;
|
||||||
|
}
|
||||||
|
g_mutex_unlock (&parsebin->cleanup_lock);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue