Commit Graph

6 Commits

Author SHA1 Message Date
Thomas Haller
dadb759c65 gobject: invoke g_object_weak_ref() one-by-one during destruction
Previously, at two places (in g_object_real_dispose() and shortly before
finalize()), we would call

    g_datalist_id_set_data (&object->qdata, quark_weak_notifies, NULL);

This clears @quark_weak_notifies at once and then invokes all
notifications.

This means, if you were inside a notification callback and called
g_object_weak_unref() on the object for *another* weak-reference, then
an exception failed:

  GLib-GObject-FATAL-CRITICAL: g_object_weak_unref_cb: couldn't find weak ref 0x401320(0x16b9fe0)

Granted, maybe inside a GWeakNotify you shouldn't call much of anything
on where_the_object_was. However, unregistering things (like calling
g_object_weak_unref()) should still reasonably work.

Instead, now remove each weak notification one by one and invoke it.

As we now invoke the callbacks in a loop, if a callee registers a new
callback, then that one gets unregistered right away too.  Previously,
we would during g_object_real_dispose() only notify the notifications
that were present when the loop starts. This is similar to what happens
in closure_array_destroy_all(). This is a change in behavior, but it
will be fixed in a separate follow-up commit.

https://gitlab.gnome.org/GNOME/glib/-/issues/1002
2025-05-07 21:29:37 +00:00
Thomas Haller
d2e08b7dfe gobject: preserve order of weak notifications in g_object_weak_unref()
g_object_weak_unref() would have done a fast-removal of the entry, which
messes up the order of the weak notifications.

During destruction of the object we emit the weak notifications. They
are emitted in the order in which they were registered (FIFO). Except,
when a g_object_weak_unref() messes up the order. Avoid that and
preserve the order.

Now, do a memmove(), which is O(n). But note that we already track weak
references in a flat array that requires a O(n) linear search. Thus,
g_object_weak_unref() was already O(n) and that didn't change. More
importantly, users are well advised to limit themselves to a reasonably
small number of weak notifications. And for small n, the linear search
and the memmove() is an efficient solution.
2025-05-07 21:29:37 +00:00
Thomas Haller
7743c7aaa2 gobject/tests: add test for g_object_weak_ref() 2025-05-07 21:29:37 +00:00
Thomas Haller
970325b92d gobject/tests: add test checking that GWeakRef is cleared in GWeakNotify
g_object_weak_ref() documentation refers to GWeakRef as thread-safe
replacement.  However, it's not clear to me, how GWeakRef is a
replacement for a callback. I think, it means, that you combine
g_object_weak_ref() with GWeakRef, to both hold a (thread-safe) weak
reference and get a notification on destruction.

Add a test, that GWeakRef is already cleared inside the GWeakNotify
callback.
2024-01-31 12:42:02 +01:00
Philip Withnall
b2272ffb81 tests: Add SPDX license headers automatically
Add SPDX license (but not copyright) headers to all files which follow a
certain pattern in their existing non-machine-readable header comment.

This commit was entirely generated using the command:
```
git ls-files gobject/tests/*.[ch] | xargs perl -0777 -pi -e 's/\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/\n \*\n \* SPDX-License-Identifier: LGPL-2.1-or-later\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/igs'
```

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #1415
2022-06-01 12:17:28 +01:00
Emmanuel Fleury
4e02be948b Moving gobject tests from tests/gobjects to gobjects/tests
The test files concerned are:

- tests/gobjects/accumulator.c
- tests/gobjects/defaultiface.c
- tests/gobjects/deftype.c
- tests/gobjects/dynamictype.c
- tests/gobjects/override.c
- tests/gobjects/references.c
- tests/gobjects/signals.c
- tests/gobjects/singleton.c

Related to issue #1434
2022-05-26 19:13:19 +01:00