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>
They just listed built files. Since the move to Meson, these are all
kept in a separate build directory, not the source tree, so don’t need
to be ignored.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
They take too long and time out, and are not particularly useful to run
under valgrind because they aren’t designed to test code coverage.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Since commit 45b5a6c0 GSlice is just a wrapper to g_malloc0/g_free, so
there's no point to use a different implementation for UNIXes vs
windows.
This reverts commit 3b7af4dd5d.
We have to ensure that the memory location is sufficiently aligned to
store any object. This unbreaks the code for CHERI where using gsize
results in values that are only aligned to 8 bytes, but we need 16 byte
alignment for pointers. This is fully API/ABI compatible since amount
of padding before the actual allocation does not change for existing
architectures, only for CHERI.
Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842
In all these cases we don't really care about running the test file,
while building and basic execution it is relevant.
Also they don't support TAP at all.
Meson supports tap protocol results parsing, allowing us to track better
the tests that are running (and the ones that are actually skipped) without
manually parsing the test output.
However this also implies that using the verbose mode for a test doesn't
show its output by default (unless there are failures).
This reverts commit da7a31a052. The renaming of parameters implicitly introduced "closure" annotations in the documentation which are wrong on callbacks.
The gobject-introspection build goes through the GLib types when
generating the introspection data for GLib, but it does not include
glib-object.h, otherwise all GObject symbols would end up inside the
GLib namespace. This means we need to import the gobject-visibility.h
header inside glib-types.h. Since the header is guarded by a once
pragma, it doesn't really affect any legitimate user of the C API.
We cannot use `gvisibility_h` for different visibility header files; you
never know when you're going to refer to the variable again, and
projects might end up needing to retrieve the variable contents—like,
for instance, gobject-introspection using glib as a subproject.
This can cause a `NULL` dereference on the next line if there is no
`TypeNode` for `iface_type`, for example if `iface_type ==
G_TYPE_INVALID`.
Unlikely, but possible since this API is public.
Spotted by Coverity.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1501602
We can get a "-Wcast-align", if the target type that we cast to ("ct") has a
larger alignment than GTypeInstance.
That can happen on i686 architecture, if the GObject type has larger
alignment than the parent struct (or GObject). Since on i686, embeding
a "long long" or a "long double" in a struct still does not increase
the alignment beyond 4 bytes, this usually only happens when using the
__attribute__() to increase the alignment (or to have a field that has
the alignment increased).
It can happen on x86_64 when having a "long double" field.
The compiler warning is hard to avoid but not very useful, because it purely
operates on the pointer types at compile time. G_TYPE_CHECK_INSTANCE_CAST()
instead asserts (in non-optimized mode) that the pointer really points
to the expected GTypeInstance (and if that's the case, then the alignment
should be suitable already).
This is like in commit ed553e8e30 ('gtype: Eliminate -Wcast-align warnings
with G_TYPE_CHECK_INSTANCE_CAST'). But also fix the optimized code path.
With the unpatched G_TYPE_CHECK_INSTANCE_CAST() macro, the unit test would
now show the problem (with gcc-9.3.1-2.fc30.i686 or
gcc-12.2.1-4.fc37.x86_64):
$ export G_DISABLE_CAST_CHECKS=1
$ export CFLAGS='-Wcast-align=strict'
$ meson build
$ ninja -C build
...
In file included from ../gobject/gobject.h:26,
from ../gobject/gbinding.h:31,
from ../glib/glib-object.h:24,
from ../gobject/tests/objects-refcount1.c:2:
../gobject/tests/objects-refcount1.c: In function ‘my_test_dispose’:
../gobject/gtype.h:2523:42: warning: cast increases required alignment of target type [-Wcast-align]
2523 | # define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip)
| ^
../gobject/gtype.h:517:66: note: in expansion of macro ‘_G_TYPE_CIC’
517 | #define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type))
| ^~~~~~~~~~~
../gobject/tests/objects-refcount1.c:9:37: note: in expansion of macro ‘G_TYPE_CHECK_INSTANCE_CAST’
9 | #define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
../gobject/tests/objects-refcount1.c:96:10: note: in expansion of macro ‘MY_TEST’
96 | test = MY_TEST (object);
| ^~~~~~~
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.
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).
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.
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.
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.
They return floating references, so that should be reflected in the
introspection annotations.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
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.
This reverts commit 756b424cce.
The freedesktop SDK, which is used by gnome-build-meta, only has Meson
0.63. Bumping GLib’s Meson dependency to 0.64 means that, at the moment,
GLib is not buildable in gnome-build-meta and hence can’t be tested in
nightly pipelines against other projects, etc.
That’s bad for testing GLib.
It’s arguably bad that we’re restricted to using an older version of
Meson than shipped by Debian Testing, but that’s a separate discussion
to be had.
Revert the Meson 0.64 dependency until the freedesktop SDK ships Meson ≥
0.64. This also means reverting the simplifications to use of
`gnome.mkenum_simple()`.
See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3077#note_1601064
Meson now uses find_program() to get glib-mkenum from glib instead of
from system. That was already fixed at least in >=0.60 which is our
current minimum requirement.
Otherwise this test will succeed at build-time, but will fail when run
as an as-installed test via ginsttest-runner.
Signed-off-by: Simon McVittie <smcv@collabora.com>
This can be used to mark entire types as deprecated,
and trigger a warning when they are instantiated
and `G_ENABLE_DIAGNOSTIC=1` is set in the environment.
There's currently no convenient macros for defining
types with the new flag, but you can do:
```c
_G_DEFINE_TYPE_EXTENDED_BEGIN (GtkAppChooserWidget,
gtk_app_chooser_widget,
GTK_TYPE_WIDGET,
G_TYPE_FLAG_DEPRECATED)
...
_G_DEFINE_TYPE_EXTENDED_END ()
```
Includes a unit test by Philip Withnall.
This reverts commit 476e33c3f3.
We’ve decided to remove `G_OS_DARWIN` in favour of recommending people
use `__APPLE__` instead. As per the discussion on #2802 and linked
issues,
* Adding a new define shifts the complexity from “which of these
platform-provided defines do I use” to “which platform-provided
defines does G_OS_DARWIN use”
* There should ideally be no cases where a user of GLib has to use
their own platform-specific code, since GLib should be providing
appropriate abstractions
* Providing a single `G_OS_DARWIN` to cover all Apple products (macOS
and iOS) hides the complexity of what the user is actually testing:
are they testing for the Mach kernel, the Carbon and/or Cocoa user
space toolkits, macOS vs iOS vs tvOS, etc
Helps: #2802
The SPDX-License-Identifier said LGPL-2.1-or-later, but the license
grant was a permissive license, which we now identify as
LicenseRef-old-glib-tests.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Some of GLib's unit tests are under an apparently GLib-specific
permissive license, vaguely similar to the BSD/MIT family but with the
GPL's lack-of-warranty wording. This is not on SPDX's list of
well-known licenses, so we need to use a custom license name prefixed
with LicenseRef if we want to represent this in SPDX/REUSE syntax.
Most of the newer tests seem to be licensed under LGPL-2.1-or-later
instead.
Signed-off-by: Simon McVittie <smcv@collabora.com>
This allows them to be referenced in other symbols value computation.
In addition, this fixes the automatically assigned value of a public
symbol that is preceded by a private one:
typedef enum {
/*< private >*/
ENUM_VALUE_PRIVATE,
/*< public >*/
ENUM_VALUE_PUBLIC, <--- value is 1, not 0.
} SomeExampleEnum;