[Bug 784383] GST_REFCOUNTING is not trustful

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Fri Jun 30 14:28:02 UTC 2017


https://bugzilla.gnome.org/show_bug.cgi?id=784383

--- Comment #2 from Martin Maurer <martin2.maurer at zeiss.com> ---
Similar code in 1.12.1 and 1.12.0, analysis based on 1.12.0.

GstMiniObject *
gst_mini_object_ref (GstMiniObject * mini_object)
{
  g_return_val_if_fail (mini_object != NULL, NULL);
  /* we can't assert that the refcount > 0 since the _free functions
   * increments the refcount from 0 to 1 again to allow resurecting
   * the object
   g_return_val_if_fail (mini_object->refcount > 0, NULL);
   */

  GST_TRACER_MINI_OBJECT_REFFED (mini_object, mini_object->refcount + 1);
  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p ref %d->%d", mini_object,
      GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object),
      GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) + 1);

  g_atomic_int_inc (&mini_object->refcount);

  return mini_object;
}


Debug Output is before semaphore/atomic int operation.
If 2 threads reach this function, both time the same counter is displayed,
even when second caller has to wait till integer is free to access again.


void
gst_mini_object_unref (GstMiniObject * mini_object)
{
  g_return_if_fail (mini_object != NULL);

  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p unref %d->%d",
      mini_object,
      GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object),
      GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) - 1);

  g_return_if_fail (mini_object->refcount > 0);

  if (G_UNLIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
    gboolean do_free;

    GST_TRACER_MINI_OBJECT_UNREFFED (mini_object, mini_object->refcount);
    if (mini_object->dispose)
      do_free = mini_object->dispose (mini_object);
    else
      do_free = TRUE;

    /* if the subclass recycled the object (and returned FALSE) we don't
     * want to free the instance anymore */
    if (G_LIKELY (do_free)) {
      /* there should be no outstanding locks */
      g_return_if_fail ((g_atomic_int_get (&mini_object->lockstate) &
LOCK_MASK)
          < 4);

      if (mini_object->n_qdata) {
        call_finalize_notify (mini_object);
        g_free (mini_object->qdata);
      }
      GST_TRACER_MINI_OBJECT_DESTROYED (mini_object);
      if (mini_object->free)
        mini_object->free (mini_object);
    }
  } else {
    GST_TRACER_MINI_OBJECT_UNREFFED (mini_object, mini_object->refcount);
  }
}

Same again here. Debug output is before atomic operation,
not inside/part of atomic operation.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list