+2005-10-12 Wim Taymans <wim@fluendo.com>
+
+ * gst/gstbin.c: (gst_bin_add_func), (gst_bin_remove_func),
+ (reset_degree), (gst_bin_dispose), (bin_bus_handler):
+ * gst/gstelement.c: (gst_element_commit_state),
+ (gst_element_set_state):
+ Protect flags with proper lock.
+ unref provided cached clock in dispose.
+
2005-10-12 Stefan Kost <ensonic@users.sf.net>
* gst/gst.c:
{
gchar *elem_name;
GstIterator *it;
+ gboolean is_sink;
/* we obviously can't add ourself to ourself */
if (G_UNLIKELY (GST_ELEMENT_CAST (element) == GST_ELEMENT_CAST (bin)))
/* get the element name to make sure it is unique in this bin. */
GST_LOCK (element);
elem_name = g_strdup (GST_ELEMENT_NAME (element));
+ is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK);
GST_UNLOCK (element);
GST_LOCK (bin);
goto had_parent;
/* if we add a sink we become a sink */
- if (GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK)) {
+ if (is_sink) {
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "element \"%s\" was sink",
elem_name);
GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_IS_SINK);
{
gchar *elem_name;
GstIterator *it;
+ gboolean is_sink;
GST_LOCK (element);
/* Check if the element is already being removed and immediately
GST_OBJECT_FLAG_SET (element, GST_ELEMENT_UNPARENTING);
/* grab element name so we can print it */
elem_name = g_strdup (GST_ELEMENT_NAME (element));
+ is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK);
GST_UNLOCK (element);
/* unlink all linked pads */
bin->children_cookie++;
/* check if we removed a sink */
- if (GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK)) {
+ if (is_sink) {
GList *other_sink;
/* check if we removed the last sink */
static void
reset_degree (GstElement * element, GstBinSortIterator * bit)
{
+ gboolean is_sink;
+
/* sinks are added right away */
- if (GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK)) {
+ GST_LOCK (element);
+ is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK);
+ GST_UNLOCK (element);
+
+ if (is_sink) {
add_to_queue (bit, element);
} else {
/* others are marked with 0 and handled when sinks are done */
bin->messages = NULL;
gst_object_unref (bin->child_bus);
bin->child_bus = NULL;
+ gst_object_replace ((GstObject **) & bin->provided_clock, NULL);
while (bin->children) {
gst_bin_remove (bin, GST_ELEMENT_CAST (bin->children->data));
/* we can lock, either the state change is sync and we can
* recursively lock or the state change is async and we
- * lock when the bin has done it state change. We can check which
+ * lock when the bin has done its state change. We can check which
* case it is by looking at the CHANGING_STATE flag. */
GST_STATE_LOCK (bin);
GST_DEBUG_OBJECT (bin, "locked");
+ GST_LOCK (bin);
if (!GST_OBJECT_FLAG_IS_SET (bin, GST_ELEMENT_CHANGING_STATE)) {
+ GST_UNLOCK (bin);
GST_DEBUG_OBJECT (bin, "got ASYNC message, forcing recalc state");
GST_STATE_UNLOCK (bin);
/* force bin state recalculation on async messages. */
gst_bin_recalc_state (bin, TRUE);
} else {
+ GST_UNLOCK (bin);
GST_STATE_UNLOCK (bin);
GST_DEBUG_OBJECT (bin, "got SYNC message");
}
GstState current, next;
GstMessage *message;
+ GST_LOCK (element);
GST_OBJECT_FLAG_SET (element, GST_ELEMENT_CHANGING_STATE);
+ GST_UNLOCK (element);
old_state = GST_STATE (element);
/* this is the state we should go to next */
} else {
GST_STATE_BROADCAST (element);
}
+ GST_LOCK (element);
GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_CHANGING_STATE);
+ GST_UNLOCK (element);
}
return ret;
}
gst_element_state_get_name (state));
GST_STATE_LOCK (element);
+
+ GST_LOCK (element);
GST_OBJECT_FLAG_SET (element, GST_ELEMENT_CHANGING_STATE);
+ GST_UNLOCK (element);
old_ret = GST_STATE_RETURN (element);
/* previous state change returned an error, remove all pending
ret = gst_element_change_state (element, transition);
+ GST_LOCK (element);
GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_CHANGING_STATE);
+ GST_UNLOCK (element);
GST_STATE_UNLOCK (element);
GST_DEBUG_OBJECT (element, "returned %d", ret);
was_busy:
{
GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
+ GST_LOCK (element);
GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_CHANGING_STATE);
+ GST_UNLOCK (element);
GST_STATE_UNLOCK (element);
GST_DEBUG_OBJECT (element, "element was busy with async state change");