miniobject: fix error in the weak ref handling

When 2 weak refs are added, the array is not resized big enough.
Simplify the weak ref handling code.
Free memory when we remove all weak refs.
Allow installing the same weak ref multiple times, like in gobject.
This commit is contained in:
Wim Taymans 2012-06-15 10:56:13 +02:00
parent 12aefaa078
commit e57cda1429

View file

@ -398,29 +398,12 @@ gst_mini_object_weak_ref (GstMiniObject * object,
g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (object) >= 1); g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (object) >= 1);
G_LOCK (weak_refs_mutex); G_LOCK (weak_refs_mutex);
i = object->n_weak_refs++;
if (object->n_weak_refs) { object->weak_refs =
/* Don't add the weak reference if it already exists. */ g_realloc (object->weak_refs,
for (i = 0; i < object->n_weak_refs; i++) { sizeof (object->weak_refs[0]) * object->n_weak_refs);
if (object->weak_refs[i].notify == notify &&
object->weak_refs[i].data == data) {
g_warning ("%s: Attempt to re-add existing weak ref %p(%p) failed.",
G_STRFUNC, notify, data);
goto found;
}
}
i = object->n_weak_refs++;
object->weak_refs =
g_realloc (object->weak_refs, sizeof (object->weak_refs[0]) * i);
} else {
object->weak_refs = g_malloc0 (sizeof (object->weak_refs[0]));
object->n_weak_refs = 1;
i = 0;
}
object->weak_refs[i].notify = notify; object->weak_refs[i].notify = notify;
object->weak_refs[i].data = data; object->weak_refs[i].data = data;
found:
G_UNLOCK (weak_refs_mutex); G_UNLOCK (weak_refs_mutex);
} }
@ -438,28 +421,28 @@ void
gst_mini_object_weak_unref (GstMiniObject * object, gst_mini_object_weak_unref (GstMiniObject * object,
GstMiniObjectWeakNotify notify, gpointer data) GstMiniObjectWeakNotify notify, gpointer data)
{ {
guint i;
gboolean found_one = FALSE; gboolean found_one = FALSE;
g_return_if_fail (object != NULL); g_return_if_fail (object != NULL);
g_return_if_fail (notify != NULL); g_return_if_fail (notify != NULL);
G_LOCK (weak_refs_mutex); G_LOCK (weak_refs_mutex);
for (i = 0; i < object->n_weak_refs; i++) {
if (object->n_weak_refs) { if (object->weak_refs[i].notify == notify &&
guint i; object->weak_refs[i].data == data) {
found_one = TRUE;
for (i = 0; i < object->n_weak_refs; i++) if (--object->n_weak_refs == 0) {
if (object->weak_refs[i].notify == notify && /* we don't shrink but free when everything is gone */
object->weak_refs[i].data == data) { g_free (object->weak_refs);
found_one = TRUE; object->weak_refs = NULL;
object->n_weak_refs -= 1; } else if (i != object->n_weak_refs)
if (i != object->n_weak_refs) object->weak_refs[i] = object->weak_refs[object->n_weak_refs];
object->weak_refs[i] = object->weak_refs[object->n_weak_refs]; break;
}
break;
}
} }
G_UNLOCK (weak_refs_mutex); G_UNLOCK (weak_refs_mutex);
if (!found_one) if (!found_one)
g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data); g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data);
} }