2414 Commits

Author SHA1 Message Date
Thomas Haller
0adb9a0b9f gobject: drop OPTIONAL_BIT_LOCK_TOGGLE_REFS lock
It was replaced by the GData lock and g_datalist_id_update_atomic().

Note that we introduced object_bit_lock() to replace global mutexes.
Now, object_bit_lock() is itself completely replaced, by the GData lock
(and hooking it via g_datalist_id_update_atomic()).

This means, all mutex-like locks now only go through the GData lock on
the GObject's qdata.

The object_bit_lock() API is still here, because it might be useful. For
example, there might be cases where the GData lock is not sufficient.

Also, we introduced GObjectPrivate mainly for object_bit_lock(). On 32
bit architecture, there is an overhead with that, as we cannot fit the
optional_flags into GObject. This is not dropped either. The optional
flags seem rather useful even without the object_bit_lock(). For
example, the OPTIONAL_FLAG_EVER_HAD_WEAK_REF flag is an important
optimization.
2025-02-21 15:03:23 +01:00
Thomas Haller
6309052917 gobject: rework g_object_remove_toggle_ref() to use g_datalist_id_update_atomic() 2025-02-21 15:03:23 +01:00
Thomas Haller
eb18740370 gobject: rework g_object_add_toggle_ref() to use g_datalist_id_update_atomic() 2025-02-21 15:03:23 +01:00
Thomas Haller
4379e9f553 gobject: rework toggle_refs_check_and_ref() to use g_datalist_id_update_atomic()
Note that OBJECT_HAS_TOGGLE_REF() is no longer used. This is good and
bad.

What we soon will do, is drop the OPTIONAL_BIT_LOCK_TOGGLE_REFS lock,
and only call g_datalist_id_update_atomic(). This way, we only need to
take the GData lock.

However, g_datalist_id_update_atomic() also needs to do a linear search
for quark_toggle_refs key. Previously, with OBJECT_HAS_TOGGLE_REF() we
didn't require this.

So the new approach is only faster, if searching the GQuark key is
reasonably fast. As GData tracks the objects in a linear list, adding
many keys can degrade and result in bad performance.

But the solution for that problem is to improve GData so that it's fast
enough for our purposes. Saying we cannot use it because it's too slow
to find the key, is wrong.
2025-02-21 15:03:23 +01:00
Thomas Haller
7cd3bed006 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 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 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.

https://gitlab.gnome.org/GNOME/glib/-/issues/1002
2025-02-21 15:03:23 +01:00
Thomas Haller
13f5d99c29 gobject: fix race and use g_datalist_id_update_atomic() for weak refs
Note that we have two calls

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

that don't take OPTIONAL_BIT_LOCK_WEAK_REFS lock. One is right before
finalize(). At that point, no other thread can hold a reference to the
object to race. One call is from g_object_real_dispose(). At this point,
theoretically the object could have been resurrected and a pointer
passed to another thread, so it can race against g_object_weak_ref()
and g_object_weak_unref().

Fix that, by performing all operations on the WeakRefStack while holding
the GData lock. By using g_datalist_id_update_atomic(), we no longer
need the OPTIONAL_BIT_LOCK_WEAK_REFS lock. On the other hand, we might
now do slightly more work while holding the GData lock.

Also, during g_object_weak_unref() free the WeakRefStack, if there
are no more references.
2025-02-21 15:03:23 +01:00
Thomas Haller
0ae9570afc gobject: fix race and use g_datalist_id_update_atomic() for closure array
There are two calls to

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

that don't take a OPTIONAL_BIT_LOCK_CLOSURE_ARRAY lock.

One is right before finalize(), at which point it's most likely safe, as
nobody else should have a reference to the object to do anything
concurrently.

The other one is in g_object_real_dispose(). Usually, at this point too
no other thread has have a reference to the object. However, it could
obtain one by dispose() passing on a reference. In that case, the
removal of the quark_closure_array data can race against
g_object_watch_closure() and object_remove_closure().

Fix that, by having all operations on the CArray performed under a lock.
In this case, using the GData lock via g_datalist_id_update_atomic().

This also saves the additional OPTIONAL_BIT_LOCK_CLOSURE_ARRAY lock.
At the expense of doing slightly more work while holding the GData lock.

Also free the empty closure data during object_remove_closure(). This
frees some unused memory.
2025-02-21 15:03:23 +01:00
Thomas Haller
2d5a00707b gdataset: add "already_locked" argument to g_datalist_id_update_atomic()
This allows the caller to take the lock on the GData first, and perform
some operations.

This is useful under the assumption, that the caller can find cases
where calling g_datalist_id_update_atomic() is unnecessary, but it's
still necessary to perform that check while holding a lock.

That will yield better performance, if we can avoid calling
g_datalist_id_update_atomic(). That matters for checking the
toggle-notify in g_object_ref()/g_object_unref().

Note that with "already_locked", g_datalist_id_update_atomic() will
still unlock the GData at the end. That is because the API of
g_datalist_id_update_atomic() requires that it might re-allocate the
buffer, and it can do a more efficient unlock in that case, instead of
leaving it to the caller. The usage and purpose of this parameter is
very special, so this asymmetry is taken because the only callers will
be fine with this behavior, and it results in potentially more efficient
unlocking.
2025-02-21 15:03:23 +01:00
Thomas Haller
ff75406feb gobject: rework freezing once during object initialization
During object initialization, we may want to freeze the notifications,
but only do so once (and once unfreeze at the end).

Rework how that was done. We can avoid an additional GData lookup.
2025-02-21 15:03:23 +01:00
Thomas Haller
5c2cc5882a gobject: don't pass around the GObjectNotifyQueue instance
By now, GObjectNotifyQueue gets reallocated. So quite possibly if we
keep the queue, it is a dangling pointer.

That is error prone, but it's also unnecessary. All we need to know is
whether we bumped the freeze count and need to unfreeze. The queue
itself was not useful, because we anyway must take a lock (via
g_datalist_id_update_atomic()) to do anything with it.

Instead, use a nqueue_is_frozen boolean variable.
2025-02-21 15:03:23 +01:00
Thomas Haller
0b3c3089f6 gobject: rework GObjectNotifyQueue to not use GSList
GSList is almost in all use cases a bad choice. It's bad for locality
and requires a heap allocation per entry.

Instead, use an array, and grow the buffer exponentially via realloc().

Now, that we use g_datalist_id_update_atomic(), it is also easy to
update the pointer. Hence, the GObjectNotifyQueue struct does not point
to an array of pspecs. Instead the entire GObjectNotifyQueue itself gets
reallocated, thus saving one heap allocation for the separate head
structure.
2025-02-21 15:03:23 +01:00
Thomas Haller
2ff1ca9f68 gobject: drop OPTIONAL_BIT_LOCK_NOTIFY lock
Now all accesses to quark_notify_queue are guarded by the GData lock.
Several non-trivial operations are implemented via
g_datalist_id_update_atomic().

The OPTIONAL_BIT_LOCK_NOTIFY lock is thus unnecessary and can be dropped.

Note that with the move to g_datalist_id_update_atomic(), we now
potentially do more work while holding the GData lock (e.g. some code
paths allocation additional memory). But note that
g_datalist_id_set_data() already has code paths where it must allocate
memory to track the GDataElt. Also, most objects are not used in
parallel, so holding the per-object (per-GData) lock longer does not
affect them. Also, many operations also require a object_bit_lock(), so
it's unlikely that you really could achieve higher parallelism by taking
more locks (and minimizing the time to hold the GData lock).
2025-02-21 15:03:23 +01:00
Thomas Haller
7932b56c47 gobject: rework g_object_notify_queue_add() to use g_datalist_id_update_atomic()
The goal is to drop OPTIONAL_BIT_LOCK_NOTIFY lock. This is one step.
Move code inside g_datalist_id_update_atomic().
2025-02-21 15:03:23 +01:00
Thomas Haller
5d81e243d4 gobject: rework g_object_notify_queue_thaw() to use g_datalist_id_update_atomic()
The goal is to drop OPTIONAL_BIT_LOCK_NOTIFY lock. This is one step.
Move code inside g_datalist_id_update_atomic().
2025-02-21 15:03:23 +01:00
Thomas Haller
626b6518b3 gobject: rework g_object_notify_queue_freeze() to use g_datalist_id_update_atomic()
A common pattern is to look whether a GData entry exists, and if it
doesn't, add it.

For that, we currently always must take a OPTIONAL_BIT_LOCK_NOTIFY lock.

This can be avoided, because GData already uses an internal mutex. By
using g_datalist_id_update_atomic(), we can perform all relevant
operations while holding that mutex.

Move functionality from g_object_notify_queue_freeze() inside
g_datalist_id_update_atomic().

The goal will be to drop the OPTIONAL_BIT_LOCK_NOTIFY lock in a later
commit.
2025-02-21 15:03:23 +01:00
Thomas Haller
87a34c37a7 gobject: avoid GLIB_PRIVATE_CALL() for g_datalist_id_update_atomic
Cache the function pointer for g_datalist_id_update_atomic() in a static
variable to avoid looking it up repeatedly.

g_datalist_id_update_atomic() is anyway internal API. And just like
GData is not a very useful data structure in general, it's mainly used
by GObject. And since GObject is the at the code, optimizing this makes
sense.

We can easily see that we never call g_datalist_id_update_atomic()
without having a GObject at hand (because we call it on
`&object->qdata`. Thus initializing the pointer in
g_object_do_class_init() (under lock) works perfectly fine. And if this
invariant ever changes, you will get a crash immediately and notice the
problem.
2025-02-21 15:03:23 +01:00
Thomas Haller
1f0f5afe20 gdataset: drop "key_id" argument from GDataListUpdateAtomicFunc
None of the users actually care about this parameter. And it's unlikely
that they ever will. Also, the passed "key_id" is the argument from
g_datalist_id_update_atomic(). If the caller really cared to know the
"key_id" in the callback, they could pass it as additional user data.
2025-02-21 15:03:22 +01:00
Marco Trevisan (Treviño)
00ebf4e1eb tests/lib: Add a new unittest type to simplify launching test programs
We were reusing the same logic everywhere, while we can just reuse an
unique class to base our tests on that avoids having to copy-and-paste
code for no good reason
2025-02-11 18:51:15 +01:00
Marco Trevisan (Treviño)
4bcd99de43 tests: Avoid reusing and installing multiple files the taptestrunner
Add some basic support for having glib-tests-only python libraries that
can be shared across the various projects, so that we don't have to
maintain multiple copies of them.
2025-02-11 18:51:15 +01:00
Philip Withnall
ca760eeeac Merge branch 'windows-fix-shebang' into 'main'
Windows: fix Python path can contain spaces

Closes #3331

See merge request GNOME/glib!4391
2025-02-11 13:42:32 +00:00
Dan Yeaw
160e55575e Windows: fix Python path cannot contain spaces
Move the shebang line from the full Python path of the build
machine to the first Python on the path during runtime. Set
the shebang in the main meson.build file so that it can be
overridden in one place if needed.

Fixes: #3331
2025-02-11 11:57:30 +00:00
Arjan Molenaar
04acc1741b
docs: Make docs more markdown-ish
Fixed some issues that came to light while compiling documentation
for the python bindings.
2025-02-10 10:26:42 +01:00
Emmanuele Bassi
dc86ad1925 Drop TypeNode reference counting
We don't allow unloading types, both static and dynamic, since 2013. The
code that deals with reference counting is mostly dead code, and makes
reasoning about the type system more complicated than necessary.

Since type classes and interfaces can only be instantiated, we introduce
explicit getter functions that create a GTypeClass or a GTypeInterface
vtable; the ref() and unref() API gets a "soft" deprecation (explicitly
not using `GOBJECT_DEPRECATED_IN_*` yet), to allow people to
progressively port their code.
2025-02-03 14:38:24 +00:00
arujjval
b67d6ec9ff
corrected Memory management of signal handlers anchor 2025-01-10 12:51:45 +05:30
Philip Withnall
68388cf7f7 Merge branch 'mcatanzaro/#3558' into 'main'
Remove incorrect (inout) annotations from GWeakRef

Closes #3558

See merge request GNOME/glib!4426
2024-12-29 18:49:08 +00:00
Simon McVittie
a4d084e975 gio, gobject: Improve reproducibility of enumtypes headers
`@filename@` expands to the (absolute or relative) path from the
build directory to the source directory, which can be rather verbose.
In practice Meson usually (always?) generates a relative path, but
even so, the resulting installed header is not necessarily reproducible
if using different build directories outside the source directory.

We don't really need a full path here anyway: the basename is enough
of a hint to point a reader towards the file where the underlying
enum was defined.

Signed-off-by: Simon McVittie <smcv@collabora.com>
2024-12-13 23:40:32 +00:00
Michael Catanzaro
15edbef3a0 Remove incorrect (inout) annotations from GWeakRef
These are in parameters, not inout parameters.

Fixes #3558
2024-12-10 08:51:07 -06:00
Maximiliano Sandoval
c1fcc7be49
gparam: Add link to constructed vfunc to CONSTRUCT
The docs for the constructed vfunc make it clear that when called
constructed properties are already set. However, the first place where a
user would look for is the flag's documentation.
2024-12-06 18:07:47 +01:00
Sid
0a68b172be gsignal: Add clarification on 'detailed_signal' validation
Fixes: https://gitlab.gnome.org/GNOME/glib/-/issues/3540
2024-12-02 14:28:59 +00:00
Jan-Willem Harmannij
80ba36e095 Add missing (array zero-terminated=1) annotations
Array annotations were missing on `g_enum_register_static` and
`g_flags_register_static`.

Fixes #3524
2024-11-06 22:26:06 +01:00
stefan11111
89480c2e0a fix https://gitlab.gnome.org/GNOME/glib/-/issues/3444 2024-09-26 22:47:30 +03:00
Philip Withnall
7a7d8d548a Merge branch 'wfloat-conversion' into 'main'
build: Enable -Wfloat-conversion and fix warnings

See merge request GNOME/glib!4126
2024-09-17 17:57:11 +00:00
Philip Withnall
683cf0a1ba
tests: Fix a scan-build warning about uninitialised variables
It’s a false positive, but points to a slightly unnecessary use of a
global variable to store something which could be computed per-test.

scan-build thought that arrays of size `n_handlers` could have
uninitialised values accessed in them if `n_handlers` were to change
value part-way through a test (which it didn’t).

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-09-12 23:25:06 +01:00
Benjamin Gilbert
b7203e9406 build: Drop redundant install_tag arguments for headers
All supported versions of Meson will autodetect the tag.
2024-09-11 22:04:39 -07:00
Pablo Barciela
de7fdced7f gobjectnotifyqueue: Add G_GNUC_UNUSED in unused parameters 2024-08-13 04:40:11 +02:00
Philip Withnall
70784b99b1 Merge branch 'wsign-conversion' into 'main'
gqsort: Add g_sort_array() and deprecate g_qsort_with_data()

See merge request GNOME/glib!4127
2024-07-04 12:33:38 +00:00
Philip Withnall
f953212cc5
tests: Add a test for g_value_array_sort_with_data()
It’s deprecated, but I was modifying it anyway and it didn’t have any
coverage, so let’s add a simple test (as suggested by Michael
Catanzaro).

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-07-04 12:34:20 +01:00
Robert Royals
04b79f91e8 gobject: Fix macro name in comment; improve style
Comment referenced non-existent macro:
    G_DEFINE_TYPE_WITH_CODE_AND_PRELUDE
but it should be:
    _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE
2024-07-03 08:09:31 +01:00
Robert Royals
14b3d5da90 gobject: Remove unused variable from macro
Remove TYPE_PARENT variable from the
    _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE
macro definition.
2024-07-01 18:39:48 +01:00
Philip Withnall
b32e1b63ee
gqsort: Add g_sort_array() and deprecate g_qsort_with_data()
The latter only accepts a `gint` as the number of elements in the array,
which means that its use in `GArray` (and related array implementations)
truncates at least half the potential array size.

So, introduce a replacement for it which uses `size_t` for the number of
elements. This is inline with what `qsort()` (or `qsort_r()`) actually
does. Unfortunately we can’t directly use `qsort_r()` because it’s not
guaranteed to be a stable sort.

This fixes some `-Wsign-conversion` warnings (when building GLib with
that enabled).

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

Helps: #3405
2024-06-28 15:27:18 +01:00
Philip Withnall
e35cfef509
performance: Add explicit casts for some double → other numeric type conversions
If we enable `-Wfloat-conversion`, these warn about a possible loss of
precision due to an implicit conversion from `double` to some other
numeric type.

The warning is correct: there is a possible loss of precision here. In
these instances, we don’t care, as the floating point arithmetic is
being done to do some imprecise scaling or imprecise timing. A loss of
precision is not a problem.

So, add an explicit cast to squash the warning.

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

Helps: #3405
2024-06-28 14:43:26 +01:00
Philip Withnall
b7153f5072
performance: Fix signedness of ints throughout
The tests were using a lot of signed `int`s when actually the values
being handled were always non-negative. Use `unsigned int` consistently
throughout.

Take the opportunity to move declarations of loop iterator variables
into the loops.

This introduces no functional changes.

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

Helps: #3405
2024-06-28 14:41:48 +01:00
Philip Withnall
6129f6f244
tests: Use correct numeric comparison assertions in param tests
There were various places where (signed or unsigned) integer assertions
were being used to compare `double` or `float` values, resulting in an
implicit integer conversion.

This causes a warning when building with `-Wfloat-conversion`.

Improve the specificity of the tests by using the most-specific numeric
assertions through all `param` tests.

For the conversion tests, this means using the assertion function
associated with the target type, not the source type.

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

Helps: #3405
2024-06-28 14:38:22 +01:00
Philip Withnall
665292006e
gvalue: Add explicit casts in numeric transform functions
Compiling with `-Wfloat-conversion` warns about a few implicit
conversions from `double`/`float` to other numeric types in the `GValue`
transform functions.

These warnings are correct: value transformations can result in loss of
precision. That loss of precision is understood and expected, so add
some explicit casts to squash the warnings.

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

Helps: #3405
2024-06-28 14:35:57 +01:00
Philip Withnall
cdbfef3842
gparamspecs: Define G_FLOAT_EPSILON as a float constant
Rather than defining it as a double constant. This introduces no
functional changes, but does squash some `-Wfloat-conversion` warnings.

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

Helps: #3405
2024-06-28 14:35:00 +01:00
Philip Withnall
ad5948bbf5
gparamspecs: Fix loss of precision when validating a double-typed pspec
As spotted by `-Wfloat-conversion`. Doubles which could not be
accurately represented as floats may have erroneously failed bounds
validation.

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

Helps: #3405
2024-06-28 14:24:39 +01:00
Philip Withnall
df5aa217e4
gobject: Don’t warn when setting deprecated construct property defaults
The default values for construct properties always have to be set, even
if those properties are deprecated. The code to do that is in GLib, and
not under the control of the user (unless they completely override the
`constructor` vfunc, which is not recommended). So don’t emit a warning
for that if `G_ENABLE_DIAGNOSTICS` is enabled.

In particular, this fixes deprecation warnings being emitted for
properties of a parent class when chaining up with a custom constructor,
even when none of the child class code mentions the deprecated property.

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

Fixes: #3254
2024-06-14 17:53:37 +01:00
gwillems
d6e0cf9884 gobject: fix broken links to parameters and signals naming rules 2024-05-21 22:32:20 +00:00
Philip Withnall
9fc63f93b4
gclosure: Delete old commented-out non-thread-safe code
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-04-26 00:21:15 +01:00
Philip Withnall
d97627442f
gclosure: Rename atomic bit operation macros
This just makes it a bit clearer that they’re atomic/for thread safety,
and not just NIHed bit operations with shouty names.

This introduces no functional changes.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-04-25 23:57:32 +01:00