Commit Graph

401 Commits

Author SHA1 Message Date
Thomas Haller
42bd9627a5 gobject: use g_malloc() allocator for GObjectNotifyQueue struct
The GSlice allocator is deprecated. Use g_new0() instead.
2023-12-21 07:26:50 +01:00
Thomas Haller
630d8da211 gobject: remove unused "conditional" argument from g_object_notify_queue_freeze() 2023-12-21 07:26:50 +01:00
Thomas Haller
94c735a2aa gobject: don't freeze to queue notify event in g_object_notify_by_spec_internal()
Previously:

- if the object is currently not frozen, we called
  g_object_notify_queue_freeze() once. Afterwards dispatch the event
  directly. This is probably the common case, and requires one
  notify_lock lock.

- if the object is currently frozen, we call
  g_object_notify_queue_freeze(), g_object_notify_queue_add().
  g_object_notify_queue_thaw().
  This required taking the notify_lock three times.

- if the object is currently not frozen and in_init, then we called
  g_object_notify_queue_freeze(), g_object_notify_queue_freeze(),
  g_object_notify_queue_add(). This also required to take
  the lock three times. There is another thaw at the end of
  object initialization.

That was because we first call g_object_notify_queue_freeze() to see
whether we are frozen. And depending on that, queue the event (and thaw
again).

Instead, g_object_notify_queue_add() can do the check and queueing in
one step. There is no need to call a freeze() to (conditionally) enqueue
a notification. Now only one lock is taken in all cases.

Also, g_object_notify_queue_freeze() and g_object_notify_queue_thaw()
both call g_datalist_id_get_data() (which also take a bit lock). As the
thaw is no longer necessary, the second lock is also saved.
2023-12-21 07:26:50 +01:00
Thomas Haller
a2b467624b gobject: add g_object_notify_queue_create_queue_frozen() helper
This will be used next, and is a separate commit to do a trivial thing
first.
2023-12-21 07:26:50 +01:00
Thomas Haller
9bee14ef3e gobject: avoid taking reference during g_object_thaw_notify()
Before dispatching signals (and calling out to user code), we want to
take a reference and ensure that the object stays alive.

However, a thaw may not decrease the freeze_count to zero, or there may
be no properties to notify. Avoid taking a reference in those cases.
2023-12-21 07:26:50 +01:00
Thomas Haller
95c2150d61 gobject: avoid additional freeze+thaw in g_object_thaw_notify()
It's easy to avoid.
2023-12-21 07:26:50 +01:00
Thomas Haller
f2fafdfe06 gobject: drop ref/unref from g_object_freeze_notify()
This was done since the beginning (commit e773d7dba6 ('fixed dealing
with collection/lcopy of NULL values.'). But it's not clear, why we
would need to take a reference on the calling object.

Freeze does not emit any signals/callbacks and does not call back to the
user. It just sets up some internal state.

This doesn't require to take a reference. The caller must hold a valid
reference to being with, but if that's given, there is no need to
acquire another reference.
2023-12-21 07:26:50 +01:00
Thomas Haller
28331deae2 gobject: adjust assertion for ref-count in g_object_freeze_notify()
g_atomic_int_get() returns a signed int. While we don't expect this to be ever
negative, a negative value would also indicate a bug. Adjust the check to assert
against negative ref-count too.
2023-12-21 07:26:50 +01:00
Emmanuele Bassi
fc5f986e60 Initialise the global GParamSpecPool in more places
Right now, we're assuming that GObjectClass will be initialised first
and under a lock, but that's not always the case: when traversing a list
of type, the first one might be a GTypeInterface, and if we initialise
an interface that installs a property, the whole thing comes crashing
down because the global GParamSpecPool is not initialised.

Instead of taking a lock everywhere, we can use an atomic compare and
swap; the first thread that installs a property wins the race, as any
other access to the GParamSpecPool is performed under a lock.
2023-12-19 19:53:48 +00:00
Sophie Herold
0d268c4825 Remove all nicks and blurbs from param specs
Nicks and blurbs don't have any practical use for gio/gobject libraries.
Leaving tests untouched since this features is still used by other libraries.

Closes #2991
2023-11-29 13:41:34 +00:00
Philip Withnall
70c66766f7 Merge branch 'atomic-uintptr' into 'main'
gatomic: Use g(u)intptr where appropriate

See merge request GNOME/glib!3143
2023-10-24 10:49:30 +00:00
Matthias Clasen
f471ebd300 docs: Move the GObject SECTION
Move the contents into the struct docs.

Helps: #3037
2023-10-16 23:34:24 +01:00
Matthias Clasen
e298f1a078 docs: Move floating refs documentation to Markdown
And add some new sections on strategies for avoiding designing APIs
around floating refs.

Helps: #3037
2023-10-11 14:01:29 +01:00
Alex Richardson
ab7e584e9f Cast via guintptr when adding/removing bitsflags on pointers
Round-tripping pointers via gsize is not guaranteed to work (the C standard
only requires this for (u)inptr_t) and in fact breaks on CHERI-enabled
systems such as Arm Morello where pointers are 128-bits but size_t is 64.
This means the current casts would strip the high bits of the pointer and
return a non-dereferenceable value. Fix this by casting the operand that
holds the pointer to guintptr instead of gsize.

Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842
2023-10-10 08:30:46 -07:00
Alex Richardson
a1dfecf11f Use g_once_init_{enter,leave}_pointer where appropriate
This should not result in any functional changes, but will eventually
allow glib to be functional on CHERI-enabled systems such as Morello.

Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842
2023-10-04 13:57:16 +01:00
Philip Withnall
83eb8fc359 Merge branch 'wip/chergert/separate-gweakref-from-gweaknotify-gdata' into 'main'
gobject: Separate GWeakRef from GWeakNotify

See merge request GNOME/glib!3316
2023-10-03 08:43:37 +00:00
Alex Richardson
2787e59a77 CHERI: silence two pedantic warnings
When building for CHERI with additional warning flags, implicitly
converting uintptr_t to an integer type that can't store a pointer
results in a compiler warnings. Silence two of these by adding
explicit casts.
2023-09-12 10:23:20 -07:00
Christian Hergert
eb8a33625e gobject: Separate GWeakRef from GWeakNotify
This patch is based upon Garrett Regier's work from 2015 to provide
some reliability and predictability to how disposal handles weak
reference state.

A primary problem is that GWeakRef and GWeakNotify state is shared and
therefore you cannot rely on GWeakRef status due to a GWeakNotify
calling into second-degree code.

It's important to ensure that both weak pointer locations and GWeakRef
will do the proper thing before user callbacks are executed during
disposal. Otherwise, user callbacks cannot rely on the status of their
weak pointers. That would be mostly okay but becomes an issue when
second degree objects are then disposed before any notification of
dependent object disposal.

Consider objects A and B.

`A` contains a reference to `B` and `B` contains a `GWeakRef` to `A`.
When `A` is disposed, `B` may be disposed as a consequence but has not
yet been notified that `A` has been disposed. It's `GWeakRef` may also
cause liveness issues if `GWeakNotify` on `A` result in tertiary code
running which wants to interact with `B`.

This example is analagous to how `GtkTextView` and `GtkTextBuffer` work
in text editing applications.

To provide application and libraries the ability to handle this using
already existing API, `GWeakRef` is separated into it's own GData quark
so that weak locations and `GWeakRef` are cleared before user code is
executed as a consequence of `GData` cleanup.

# Conflicts:
#	gobject/tests/signals.c
2023-08-25 14:25:47 -07:00
Philip Withnall
0196a36022 Merge branch 'more-atomic-exchange-full' into 'main'
gdataset, gobject: Use atomic compare and exchange full to set pointers

See merge request GNOME/glib!3426
2023-05-30 11:59:40 +00:00
Arnaud Rebillout
d6e57943ea Fix style-check for {gconvert,gutils,gobject}.c
Also take this chance to change a 'Glib' to 'GLib'.
2023-05-10 10:56:44 +07:00
Arnaud Rebillout
f722f11e57 Rename GTK+ to GTK (mostly comments and documentation)
GTK lost it's '+' suffix back in 2019, according to
<https://mail.gnome.org/archives/gtk-devel-list/2019-February/msg00000.html>

This commit can be re-generated with:

    git grep -l GTK+ \
    | grep -v -e ^NEWS -e ^glib/tests/collate.c \
    | xargs sed -i 's/GTK+/GTK/g'

Most of the changes are in comments and documentation.
2023-05-10 10:56:44 +07:00
Marco Trevisan (Treviño)
f792b2ce64 gobject: Use atomic compare and exchange full to force floating
In case first exchange failed we can avoid repeating the pointer get
operation given that exchange full can provide us the old value.
2023-05-09 15:04:36 +02:00
badcel
1c15f158b0
gobject: Fix some annotations 2023-02-24 18:06:14 +01:00
Marco Trevisan (Treviño)
cbb9feb6af gobject: Use some new cleaner code to set object GValues
Use some newer APIs to make the code nicer cleaner and clearer in terms of
memory ownership.
2022-12-20 17:48:21 +01:00
Marco Trevisan (Treviño)
bc59ed8fba gobject: Avoid the ref/unref dance if assigning the same to a value
g_value_set_object could lead to perform unneeded ref/unref operations in
case we were trying to set again an object to a GValue
2022-12-20 17:48:21 +01:00
Emmanuele Bassi
fde157ace4 Improve notification queue warning
Instead of a plain reference count check failure that is really hard to
understand, let's be explicit, and warn that manipulating an object's
notification queue during its finalization is not allowed.
2022-12-12 15:01:19 +00:00
Philip Withnall
bbb3453c82 Merge branch 'atomic-unref-cleanups' into 'main'
gobject: Use compare and exchange full to re-read old ref value

See merge request GNOME/glib!3098
2022-12-06 16:12:59 +00:00
Marco Trevisan (Treviño)
6cd6cc41bb gobject: Trace unref just after this happened
Trace the unref before potentially calling (user) code that may re-ref
or unref again, causing the tracing order to be messed up.
2022-12-06 04:43:02 +01:00
Marco Trevisan (Treviño)
0918ce013a gobject: Do not call toggle down notifications if current refcount is not 1
When an object is revitalized and a notify callbacks increased the reference
counter of the object, we are calling the toggle notifier twice, while it
should only happen if also the actual reference count value is 1 (after
having been decremented from 2).
2022-12-06 04:38:26 +01:00
Marco Trevisan (Treviño)
1f852863ec gobject: Check for toggle references only if the old ref is relevant
If an object gets revitalized during the dispose vfunc, we need to call
toggle refs notifiers only if we had 2 references and if the object has
the toggle references enabled.

This may change in case an object notifier handler changes this status,
so do this check only after we've called the notifiers so that in case
toggle notifications are enabled afterwards we still call the handlers.
2022-12-06 04:28:31 +01:00
Marco Trevisan (Treviño)
c0360f626c gobject: Read the toggle reference state only after we've update the references
We were reading if an object has toggle references even if this was not
really relevant for the current object state, as we only need to notify
when going from 2 to 1 references, so first ensure that this is the case
and then check if we have toggle references enabled in the object.

This is a micro-optimization, for the way flags are defined, but still
an operation we can avoid in most cases.
2022-12-06 01:22:34 +01:00
Marco Trevisan (Treviño)
30e1d69de7 gobject: Check for valid ref counting via g_return_if_fail
Even though the check is likely to be relevant if the object is finalized,
it may still give some indication if called while an instance has just lost
the last reference.

So use `g_return_if_fail` for consistency with the rest of the code.
2022-12-05 20:23:26 +01:00
Marco Trevisan (Treviño)
65303537b0 gobject: Remove initial goto to repeat unref operation 2022-12-01 16:20:46 +01:00
Marco Trevisan (Treviño)
a89048c4f1 gobject: Use a while instead of goto to repeat atomic increment
We can use a cleaner solution now that we do not require to init the
same value multiple times in the same way.
2022-11-29 21:35:04 +01:00
Marco Trevisan (Treviño)
c95bf0514c gobject: Use compare and exchange full to re-read old ref value
In case g_atomic_int_compare_and_exchange() check fails we ended up doing
another atomic get to figure out what it was the old reference count,
however, we can avoid this by using the full version of the function that
returns the value before the exchange happened as an out value.
2022-11-29 20:53:06 +01:00
Emmanuele Bassi
f1b7a52fe2 docs: Avoid unintended titles in g_object_new()
Lines should not start with `#` unless they are titles, as docblocks are
parsed as Markdown.

Fixes: #2821
2022-11-28 11:49:51 +00:00
Simon McVittie
e974c81d0a gobject: Only emit deprecation warnings for user-specified properties
If a deprecated property only gets set because it is G_PARAM_CONSTRUCT
or G_PARAM_CONSTRUCT_ONLY, then there is nothing for the library user
to fix, and we should not emit a deprecation warning.

Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2748
Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-09-21 10:27:55 +01:00
Michael Catanzaro
0ffe86a1f7 Replace most GObject warnings with criticals
All of these warnings indicate programmer error, so critical is most
appropriate here.

Exceptions: deprecation warnings are just warnings. Also, warnings that
are worded with uncertainty can remain warnings rather than criticals.
2022-08-09 13:18:47 -05:00
Peter Bloomfield
3290ebfadc gobject: Small speedup in weak-ref-set 2022-07-08 14:37:53 +00:00
Matthias Clasen
c0a618a716 gobject: Don't skip custom dispatch_properties_changed
When I optimized GObject to skip property notification
in some cases, I looked for whether the class has a
custom notify vfunc. I overlooked that that
dispatch_properties_changed can also be customized,
and if it is, we better not skip change notification.

This showed up as breakage in the adjustment tests
in the GTK testsuite.
2022-07-08 13:57:40 +01:00
Philip Withnall
ed564b71dd Merge branch '2672-dataset-tests-and-fixes' into 'main'
gdataset: Preserve destruction order

Closes #2672 and #2676

See merge request GNOME/glib!2776
2022-07-07 11:52:19 +00:00
Philip Withnall
41691cc4c8 Merge branch 'more-spdx' into 'main'
Add more SPDX license headers

See merge request GNOME/glib!2706
2022-07-05 11:06:49 +00:00
Peter Bloomfield
94ba14d542 gobject: Weaken an assertion in g_weak_ref_set()
When weak references are being cleaned up, it is possible for the `qdata` for
both `quark_weak_locations` and `quark_weak_refs` to have been deallocated,
so that `g_datalist_id_get_data()` returns `NULL` for both. This happens
when `g_object_run_dispose()` is called for the target of a `GBinding`,
and is not an error.

See https://gitlab.gnome.org/GNOME/glib/-/issues/2676
2022-07-03 14:56:44 -04:00
Simon McVittie
d4043eced5 Revert "gobject: Use g_datalist_id_remove_multiple"
This reverts commit fa8c7c0 "gobject: Use g_datalist_id_remove_multiple"
(or more specifically the parts of it that were not already reverted
in 01ac1d9 "gobject: Fix crash when disposing a GtkAccelGroup".

Workaround for https://gitlab.gnome.org/GNOME/glib/-/issues/2676

Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/2676
2022-06-26 18:00:52 +01:00
Simon McVittie
7045260c22 gsignal: Add G_CONNECT_DEFAULT
This makes calls to g_signal_connect_data() and g_signal_connect_object()
with default flags more self-documenting.

Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-06-23 10:46:45 +01:00
Philip Withnall
01ac1d902f gobject: Fix crash when disposing a GtkAccelGroup
This is a partial revert of commit fa8c7c0da using the approach
suggested (and tested) by Kjell Ahlstedt.

It is intended to be temporary pending a proper dig into what’s causing
the regression, just so we can get the 2.73.1 release out.

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

Helps: #2672
2022-06-20 16:32:00 +01:00
Philip Withnall
b2f4df95e8 Merge branch 'coverity-is-stupid' into 'main'
gobject: Change GObject notify semantics under static analysis

See merge request GNOME/glib!2747
2022-06-17 15:47:39 +00:00
Philip Withnall
0932f71460 gobject: Change GObject notify semantics under static analysis
Coverity notices the `g_object_unref()` call in `g_object_notify()`, but
not the paired `g_object_ref()` call. It therefore incorrectly assumes
that every call to `g_object_notify()` frees the object. This causes a
lot (hundreds) of false positive reports about double-frees or
use-after-frees.

I can’t find a way to fix this using a model file, so the other options
are:
 * Manually mark every report as a false positive and keep updating them
   as the code changes over time. This would take a lot of maintainer
   effort.
 * Comment out the `g_object_ref()`/`g_object_unref()` calls when
   running static analysis (but not in a normal production build). This
   is ugly, but cheap and shouldn’t impact maintainability much.

So this commit implements option 2.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2022-06-14 11:25:50 +01:00
Philip Withnall
af7ba68a00 gobject: ifdef out some inline functions if they’re not used
This prevents `-Wunused-function` warnings on platforms which don’t have
`HAVE_OPTIONAL_FLAGS` defined.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2022-06-14 11:10:09 +01:00
Matthias Clasen
10a1c16b59 Avoid atomics during construction
During construction, we have exclusive access to
the object, so there is no need to use atomics
for setting or reading the optional_flags member.
2022-06-14 11:09:53 +01:00