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.
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.
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.
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.
Generating gir and typelib files has inter-dependencies that may depend
on other elements.
For example, glib requires gobject and gdump generated files require
gmodule, so we've a cyclic dependency because gmodule requires gobject,
that requires glib.
To prevent this, let's just generate the introspection files at once in
a different meson file so that we don't have to deal with this.
As per this we could even revert commit fa37ab6d0 since gio is now
compiled before the gir files.
GLib gir requires glib-types.h that also includes gobject-visibility.h
that needs to be generated in order to be able to generate the GLib gir,
so explicitly add it to the sources.
Also, in order to link the typelib we need the definitions of the *_get_type()
functions that are defined in the gboxed.c file, so this should be part
of the gir sources or we'll have linking issues.
Aside from checking that we're accessing the global GParamSpecPool
without necessarily initializing GObjectClass, we should also verify
that we're doing so safely without the class init lock.
Ensure that the fix in commit af024b6d7e7d3fbef23c1f7d1f7704fc90ac4fb1
works, by replicating what gobject-introspection does:
- initialise the default GTypeInterface from a GType without also
initialising GObjectClass
- install a property for the interface
- find the GParamSpec using g_object_interface_find_property()
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.
While GParamSpecPool should never be used by newly written code, having
the ability to free the associated memory is a good idea. The only
reason why this hasn't been necessary until now is that we assume base
classes are going to keep their GParamSpecPool around forever.
Symptom:
20 0x00007ffff756337b in gtk_widget_size_allocate_with_baseline (widget=0xd7a0c0 [DirectWindow], allocation=, baseline=) at
gdb.error: value has been optimized out
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
Signals (as opposed to signal connections) can never be unregistered, so
these closures have to be around forever.
Fixes some g-ir-scanner warnings.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3037
Boxed types can never be unregistered, so these closures have to be
around forever.
Fixes some g-ir-scanner warnings.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3037
This allows the methods for `GDir` to be introspected. While we don’t
expect languages which use the introspection bindings to use `GDir`,
full introspection support is necessary for the `GDir` documentation to
be correctly built with gi-docgen.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3037
Otherwise the installed one will be used, which will mean that new API
will not be available when linking.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Modify all the similar Python test wrappers to set
`G_DEBUG=fatal-warnings` in the environment of the program being tested,
so we can catch unexpected warnings/criticals.
Adding this because I noticed it was missing, not because I noticed a
warning/critical was being ignored.
Signed-off-by: Philip Withnall <philip@tecnocode.co.uk>
On CHERI-enabled systems we use uintptr_t as the underlying storage for
GType and therefore casting to gsize strips the upper bits from a pointer.
Fix this by casting via uintptr_t instead and introduce a new set of
macros to convert between GType and pointers.
This is required for CHERI systems such as Arm Morello, where gsize is
not large enough to hold a pointer. As GType can contain pointers, we
have to use guintptr instead.
It needs to be in a separate page because it’s all macros and they have
no type/class associated with them.
Signed-off-by: Philip Withnall <philip@tecnocode.co.uk>
Helps: #3037
Currently, the introspection data for GLib and its sub-libraries is
generated by gobject-introspection, to avoid the cyclic dependency
between the two projects.
Since gobject-introspection is generally available on installed systems,
we can check for its presence, and generate the introspection data
directly from GLib.
This does introduce a cyclic dependency, which is why it's possible to
build GLib without introspection, then build gobject-introspection, and
finally rebuild GLib.
By having introspection data available during the GLib build, we can do
things like generating documentation; validating newly added API; and
close the loop between adding new API and it becoming available to non-C
consumers of the C ABI (i.e. language bindings).
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
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
If you take a release build (--buildtype=release) previously of GLib,
functions such as g_type_create_instance() would call out to
g_type_test_flags() which you can see by disassembling and looking for the
call instruction to <g_type_test_flags> via the library ABI.
Now that the previous commit allows checking abstract and deprecated flags
it makes sense to let the compiler optimize those checks into a single
pass. This is only possible if the functions themselves are inlined.
Additionally, any time we have the same TypeNode we would want to be able
to reuse that node rather than re-locate it.
Every call to g_type_create_instance() currently will incur a RWLock at
least once, but usually twice to test for both G_TYPE_FLAG_ABSTRACT and
G_TYPE_FLAG_DEPRECATED.
Additionally, each call to g_type_instance_free() also checks for these.
That results in a synchronization of GTypeInstance creation across all
threads as well as being a huge amount of overhead when creating instances
like GskRenderNode.
With this patch in place, the next two biggest issues are
g_type_class_ref() and g_type_test_flags() not getting inlined within
gtype.c in release builds. We can address that separately though.
Sysprof shows that the RWLock, with this patch in place, falls off the
profiles.
The introspection parser isn't good enough to expand the shift symbol,
which means G_TYPE_FUNDAMENTAL_MAX is evaluated as (255 << 0).
We can use the `(value)` annotation to force the symbol value in the
introspection data.
See: GNOME/gobject-introspection#473
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.
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
There’s no reason that anyone can think of that this should be
disallowed. It’s useful for language runtimes like GJS to be able to
find out the allocation size of dynamic GObjects.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #623
UAC will terminate this test program from running in 32-bit x86 builds as
it believes that it will alter Windows. In order to make this run, we
create a manifest file for 32-bit Windows builds in order to tell UAC
that this program should not need admin privileges.
This will allow the entire test suite for GLib to run on 32-bit Windows
builds.
Add to script the new functions added in
commit 2368187e and commit e5ee6e14 which are:
signal_emitv_unlocked()
signal_emit_valist_unlocked()
so that the "<emit signal 'blabla'>" line keeps
showing after them.
The compiler annotations are mainly useful for people using the symbols
directly.
To avoid getting compiler warnings for the GTypeValueTable definition
itself, we need to wrap the structure with
G_GNUC_BEGIN_IGNORE_DEPRECATIONS and G_GNUC_END_IGNORE_DEPRECATIONS.
The introspection scanner cannot deal very well with function pointers
into a plain structure. In order to document the various function
pointers in GTypeValueTable we need to create typed callbacks, and
use them to replace the anonymous function pointers inside the
structure. This not only allows us to properly document the function
pointers, but it also allows us to annotate the arguments and return
value of those function pointers.
See also: https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/400#note_1721707
For now, the function parse_trigraph() defined in gobject/glib-mkenums
script was not taking double-quotes characters into account:
>>> parse_trigraph('name="eek, a comma"')
{'name': '"eek', 'a': None}
This patch take double-quotes characters into account:
>>> parse_trigraph('name="eek, a comma"')
{'name': 'eek, a comma'}
Closes issue #65
Normally we don't really have emission hooks around, so try to allocate
only tiny array to contain a few of them and in case we exceed that limit,
we go back to use allocated ones.
We used to call this function as unlocked, with a node value that
could be invalid at the point of the call, so let's ensure that when
we call such function it's defined, and then reduce the access to the
signal node members when we're unlocked or after a lock/unlock operation
that may have changed it.
As per this, add more tests handling multiple signal hooks cases that we
did not cover before.
In g_signal_emit_valist() we used to access to param types array and
n_params values after unlocking the mutex, and this might have lead to
making such values unreliable for the current call.
So let's keep them around until we're done with the function call
Since we're locking and unlocking once we've found the signal ID, we
might have performed calls to g_signal_emit_valist() with a signal id
that was already been removed, and thus failing later.
This is not really an issue as inside g_signal_emit_valist() we were
re-checking for the signal id, but we can make this more reliable so
that the first thread that acquires the lock can also be sure to emit.
This is a minor style change to better differentiate
signal name by enclosing it in single quotes.
Before:
<emit signal event on instance 0xf14e60 [GdkWaylandToplevel]>
After:
<emit signal 'event' on instance 0xf14e60 [GdkWaylandToplevel]>
- Commit f02ec2f2de added a gsignal fastpath where g_closure_invoke_va()
is directly called from g_signal_emit_valist() skipping signal_emit_unlocked_R()
altogether which it's the function used by gobject_gdb.py to detect
signal emission.
So we update gobject_gdb.py to also detect signals which use this
g_closure_invoke_va() fastpath.
- We also update the existent code to detect marshallers to also
include these:
surface_event_marshaller()
gdk_surface_event_marshallerv()
g_type_class_meta_marshal()
g_type_class_meta_marshalv()
This allow us that for signal emissions which use those marshallers
to keep showing the signal handler frame just after the
<emit signal blabla> line.
commit bfbe7127d5 which did a code refactor in
gobject_gdb.py introduced a bug by failing to
return the signal name when a signal had no
'detail', this was preventing pretty printing
name for signals with no 'detail'.
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.
While x86_64 has enough precision in long double to do a round trip
from guint64 to long double and back, this is platform-specific, and
is a disservice to users trying to debug failing unit tests on other
architectures where it loses precision for g_assert_cmp{int,uint,hex}.
See also https://bugzilla.gnome.org/show_bug.cgi?id=788385 which
mentions having to add casts to specifically silence the compiler on
platforms where the precision loss occurs.
Meanwhile, g_assert_cmpuint() does an unsigned comparison, but outputs
signed values if the comparison fails, which is confusing.
Fix both issues by introducing a new g_assertion_message_cmpint()
function with a new 'u' numtype. For backwards compatibility, the
macros still call into the older g_assertion_message_cmpnum() when not
targetting 2.78, and that function still works when passed 'i' and 'x'
types even though code compiled for 2.78 and later will never invoke
it with numtype anything other than 'f'. Note that g_assert_cmpmem
can also take advantage of the new code, even though in practice,
comparison between two size_t values representing array lengths that
can actually be compiled is unlikely to have ever hit the precision
loss. The macros in signals.c test code does not have to worry about
versioning, since it is not part of the glib library proper.
Closes#2997
Signed-off-by: Eric Blake <eblake@redhat.com>
Most of the document was about traps, which have not existed since
commit 58cdf0b474, 10 years ago.
The rest of the document was about `GOBJECT_DEBUG`, and that information
would be more easily findable in the full GObject documentation — so
move it there and update it a bit.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Calling g_signal_handlers_block/unblock/disconnect_matched with only G_SIGNAL_MATCH_ID
do not match any handlers and return 0.
Fixes: #2980
Signed-off-by: Przemyslaw Gorszkowski <pgorszkowski@igalia.com>
The use of ‘OR’ in the existing documentation suggests that the matching
is disjunctive, but it’s actually conjunctive. Clarify that in the
documentation and add a test.
Spotted while reviewing
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3376.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
The documentation previously implicitly said in a few places that
interfaces are classed, but reading through the implementation of
`GType`, I don’t think they are. If they were, the registration of the
fundamental `G_TYPE_INTERFACE` in `gobject_init()` would specify
`G_TYPE_FLAG_CLASSED`. It only specifies `G_TYPE_FLAG_DERIVABLE`.
I think this makes sense, because you can’t subclass an interface.
Subclassing is a key property of being classed.
Tweak the `GType` tutorial to remove that implicit statement, and expand
the documentation for `G_TYPE_IS_CLASSED`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #252
‘returns TRUE on success’ is misleading for a lot of these macros, as
they are checking whether a type has a certain property. Such a check
could be successful but return `FALSE`, by the normal meaning of the
word ‘success’.
Instead, reword the docs to spell out when `TRUE` will be returned.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>