mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 07:16:55 +00:00
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:
parent
12aefaa078
commit
e57cda1429
1 changed files with 18 additions and 35 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue