diff options
author | David Schleef <ds@schleef.org> | 2011-08-21 14:07:08 -0700 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2011-08-21 14:07:08 -0700 |
commit | ec6e452f6314b10e883c6f95366867a02c775ff0 (patch) | |
tree | 8a05552c617402d81ffcda58849c22a08aa869fa | |
parent | cce32ba0a29cdebc34cf6bf66e72a3f554be3028 (diff) |
object: make gst_object_replace() atomic
-rw-r--r-- | gst/gstobject.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/gst/gstobject.c b/gst/gstobject.c index f06d798e4..8efadeb4c 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -421,10 +421,14 @@ gst_object_sink (gpointer object) * * Make sure not to LOCK @oldobj because it might be unreffed * which could cause a deadlock when it is disposed. + * + * Since 0.10.36, this function operates atomically. */ void gst_object_replace (GstObject ** oldobj, GstObject * newobj) { + GstObject *oldptr; + g_return_if_fail (oldobj != NULL); g_return_if_fail (*oldobj == NULL || GST_IS_OBJECT (*oldobj)); g_return_if_fail (newobj == NULL || GST_IS_OBJECT (newobj)); @@ -437,14 +441,14 @@ gst_object_replace (GstObject ** oldobj, GstObject * newobj) newobj ? G_OBJECT (newobj)->ref_count : 0); #endif - if (G_LIKELY (*oldobj != newobj)) { - if (newobj) - gst_object_ref (newobj); - if (*oldobj) - gst_object_unref (*oldobj); - - *oldobj = newobj; - } + if (newobj) + g_object_ref (newobj); + do { + oldptr = *oldobj; + } while (!g_atomic_pointer_compare_and_exchange ((void *) oldobj, + oldptr, newobj)); + if (oldptr) + g_object_unref (oldptr); } /* dispose is called when the object has to release all links |