Check whether an object has a nontrivial notify vfunc
and avoid creating and updating the notify queue if
it doesn't. We know that there can be no notify signal
handlers at this point. No need to notify if nobody's
listening.
We currently keep a flag for whether an object has
ever had any signal handlers. But even if it had signal
handlers, it may not have any notify handlers. Keep that
information separately, so we can speed up property setting.
According to the commit that introduced these
calls (4b334ef8f1), we are checking
the refcount here to avoid calling g_object_ref
when the refcount is 0, in the rare case that
notification would be triggered during finalize.
But we are now freezing notifications during
finalize, and after recent changes, we no longer call
g_object_ref for notification while a freeze is
in place.
We only need to take a ref on the object when
we call out to external code (ie around
->dispatch_properties_changed). If we avoid
the signal emission, we can avoid the ref/unref
too. This is not currently happening, but
might in the future.
A small reorg that reduces the code and matches
what we do for object_get_property.
Note that as a consequence of this change, we now
check the deprecated flag on the redirected property,
not on the original when setting properties. This
matches what we were already doing for getting
properties.
The code that emits property deprecation warnings
rarely runs, and doesn't need to be inlined
everywhere. It is enough to inline the check for
the deprecation flag.
It is safe not to copy arguments here,
because we are not emitting any signals
before we are done setting the values
as properties.
This matches what we do for g_object_new now.
We can safely use the values without copying here.
This is safe because we are not emitting any
signals before we are done setting the values
as properties.
None of these messages are particularly helpful, but they increase the
overall test log output size, which has to be stored by the CI for every
test run.
With these messages removed, the size of a full test log is reduced from
6.5MB to 1.8MB for me.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Modified by Philip Withnall to omit the subdirectory and drop the
`refcount` suite as both seem like unnecessary over-categorisation.
Related to issue #1434
This avoids walking the construct params list
one extra time just to count when constructing
objects, for a small speedup of object construction
in the presence of construct params.
Move the `if` into the precondition assertion, eliminating one line of
code and making the function preconditions clearer to static analysers.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Avoid GValue transformation when we can, using
the new value_is_valid vfunc.
This is particularly useful for string properties,
where g_value_transform will make a copy of the string.
In constrast to value_validate, this one does not
modify the passed-in value, so we can avoid the cost
of copying the GValue beforehand.
It is optional, but we set it for most of the
builtin pspec types.
In several places we do paired calls of g_value_init
and g_value_unset, both of which peek the value table.
We can avoid half of that cost by remembering the value
table, instead of looking it up again.
This uses the new G_VALUE_COLLECT_INIT2 macro.
The user data parameters in callbacks need to be named user_data to
generate correct closure attributes in the introspection data. This
updates parameters missed in GNOME/glib!2633.
As noticed by Christian Hergert: We can reduce
some overhead by checking for exact type
equality first. According to Christian, around
3% of g_type_is_a calls are exact equalities.
Using prefixed property names like GtkWidget::visible
is very deprectated and basically never done. So avoid
paying the strchr cost before doing the first lookup.
Most of the time, we are dealing with static strings,
and we can compare them directly and avoid the strcmp.
Note that triggering this optimization requires
properties to be marked as G_PARAM_STATIC_NAME.
Drop the redundant `PROP_0` (which isn’t a real property) and initialise
the first member of the enum instead.
Add a typedef so that the enum type can be used in `switch` statements
in `get_property()` and `set_property()` vfuncs. This allows
`-Wswitch-enum` to be used to improve type safety.
The examples here don’t have `get_property()` or `set_property()`
vfuncs, but people might copy/paste the code to somewhere which does.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Make it a bit clearer in the documentation that using
`G_PARAM_STATIC_STRINGS` everywhere is a good thing.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Spotted by ASAN during the tests:
Direct leak of 72 byte(s) in 1 object(s) allocated from:
#0 0x7ff0b4562077 in calloc (/lib64/libasan.so.8+0xba077)
#1 0x7ff0b3e8b508 in g_malloc0 ../glib/gmem.c:155
#2 0x7ff0b375052f in g_closure_new_simple ../gobject/gclosure.c:220
#3 0x7ff0b375b422 in g_cclosure_new ../gobject/gclosure.c:976
#4 0x7ff0b37d159e in g_signal_group_connect_full ../gobject/gsignalgroup.c:790
#5 0x7ff0b37d159e in g_signal_group_connect ../gobject/gsignalgroup.c:886
#6 0x4045d8 in test_signal_group_invalid ../gobject/tests/signalgroup.c:331
#7 0x7ff0b3f369a5 in test_case_run ../glib/gtestutils.c:2930
#8 0x7ff0b3f369a5 in g_test_run_suite_internal ../glib/gtestutils.c:3018
#9 0x7ff0b3f364ed in g_test_run_suite_internal ../glib/gtestutils.c:3035
#10 0x7ff0b3f364ed in g_test_run_suite_internal ../glib/gtestutils.c:3035
#11 0x7ff0b3f37879 in g_test_run_suite ../glib/gtestutils.c:3112
#12 0x7ff0b3f37995 in g_test_run ../glib/gtestutils.c:2231
#13 0x40253c in main ../gobject/tests/signalgroup.c:664
#14 0x7ff0b2de758f in __libc_start_call_main (/lib64/libc.so.6+0x2d58f)
Direct leak of 72 byte(s) in 1 object(s) allocated from:
#0 0x7f012addf077 in calloc (/lib64/libasan.so.8+0xba077)
#1 0x7f012a708508 in g_malloc0 ../glib/gmem.c:155
#2 0x7f0129fcd52f in g_closure_new_simple ../gobject/gclosure.c:220
#3 0x7f0129fd8422 in g_cclosure_new ../gobject/gclosure.c:976
#4 0x7f012a04e5ae in g_signal_group_connect_full ../gobject/gsignalgroup.c:791
#5 0x7f012a04e5ae in g_signal_group_connect ../gobject/gsignalgroup.c:887
#6 0x4043cc in test_signal_group_invalid ../gobject/tests/signalgroup.c:308
#7 0x7f012a7b39a5 in test_case_run ../glib/gtestutils.c:2930
#8 0x7f012a7b39a5 in g_test_run_suite_internal ../glib/gtestutils.c:3018
#9 0x7f012a7b34ed in g_test_run_suite_internal ../glib/gtestutils.c:3035
#10 0x7f012a7b34ed in g_test_run_suite_internal ../glib/gtestutils.c:3035
#11 0x7f012a7b4879 in g_test_run_suite ../glib/gtestutils.c:3112
#12 0x7f012a7b4995 in g_test_run ../glib/gtestutils.c:2231
#13 0x40253c in main ../gobject/tests/signalgroup.c:664
#14 0x7f012966458f in __libc_start_call_main (/lib64/libc.so.6+0x2d58f)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Meson generates a gdbinit file that will automatically load glib and
gobject scripts. However that script uses a helper python module that
needs PYTHONPATH to be pointing into the right location in the source
tree to be able to find glib_gdb.py and gobject_gdb.py
This won’t really affect anything, but we might as well fix them to not
crash if called with an empty `argv` by someone (ab)using `execve()`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Much like GBindingGroup, the GSignalGroup object allows you to connect many
signal connections for an object and connect/disconnect/block/unblock them
as a group.
This is useful when using many connections on an object to ensure that they
are properly removed when changing state or disposing a third-party
object.
This has been used for years in various GNOME projects and makes sense to
have upstream instead of multiple copies.
Originally, GBindingGroup started with Builder as a way to simplify all
of the third-degree object bindings necessary around Model-Controller
objects such as TextBuffer/TextView.
Over time, it has grown to be useful in a number of scenarios outside
of Builder and has been copied into a number of projects such as GNOME
Text Editor, GtkSourceView, libdazzle, and more.
It makes sense at this point to unify on a single implementation and
include that upstream in GObject directly alongside GBinding.
Glib cannot be built statically on Windows because glib, gobject and gio
modules need to perform specific initialization when DLL are loaded and
cleanup when unloaded. Those initializations and cleanups are performed
using the DllMain function which is not called with static builds.
Issue is known for a while and solutions were already proposed but never
merged (see: https://gitlab.gnome.org/GNOME/glib/-/issues/692). Last
patch is from version 2.36.x and since then the
"constructor/destructor" mechanism has been implemented and used in
other part of the system.
This patch takes back the old idea and updates it to the last version of
glib to allow static compilation on Windows.
WARNING: because DllMain doesn't exist anymore in static compilation
mode, there is no easy way of knowing when a Windows thread finishes.
This patch implements a workaround for glib threads created by calling
g_thread_new(), so all glib threads created through glib API will behave
exactly the same way in static and dynamic compilation modes.
Unfortunately, Windows threads created by using CreateThread() or
_beginthread/ex() will not work with glib TLS functions. If users need
absolutely to use a thread NOT created with glib API under Windows and
in static compilation mode, they should not use glib functions within
their thread or they may encounter memory leaks when the thread finishes.
This should not be an issue as users should use exclusively the glib API
to manipulate threads in order to be cross-platform compatible and this
would be very unlikely and cumbersome that they may mix up Windows native
threads API with glib one.
Closes#692
Notifying during object destruction is a dubious "feature": objects
might end up recreating a bunch of state just before clearing it;
language bindings might get spurious notifications during garbage
collection runs.
We freeze the notification queue before running the dispose() chain; if
the object was temporarily vivified during dispose, we thaw the
notification queue, otherwise we let the instance clear it when we
finalize it.
See: https://gitlab.gnome.org/GNOME/gjs/-/issues/445
We now guarantee that GObjects will always be allocated at least as
aligned as the basic types. If you want to put an element in your
GObject which has higher alignment requirements, we can’t guarantee it
will be aligned*. If you need it to be aligned, you’ll need to put it on
the heap (aligned appropriately), or add appropriate padding in your
GObject struct.
*Actually, GSlice will guarantee that the whole GObject is aligned to at
least the power of 2 greater than or equal to the size of the GObject,
which means any element in the GObject struct should always be
appropriate aligned if the compiler pads it appropriately. If malloc()
is used, however, it doesn’t make that guarantee, so we can’t make that
guarantee overall.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1231
Regardless of the actual alignment of the GTypeInstance in question,
these do a runtime check on the type, so if the type was originally
aligned correctly when allocated, it should be aligned correctly if the
type check succeeds. -Wcast-align is meant to warn about casts between
types, which this isn’t (if the check succeeds).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1231
See the reasoning in the patch for why we believe GObjects *are*
(already) as aligned as the basic types.
We want to make this guarantee so that it’s guaranteed to be safe for
people to ignore -Wcast-align warnings for GObjects which contain basic
types. This typically happens with gdouble on 32-bit ARM platforms.
The checks are slightly complicated by the need to support GObjects with
custom constructors. We should expect that a custom construction
function will chain up to g_object_constructor (which calls
g_type_create_instance() as normal), but it’s possible that someone has
done something crazy and uses a custom allocator which doesn’t return
with the same alignment as GSlice. Hand them a warning in that case. If
that is true, the code which uses their custom-constructed GObject can
presumably already deal with the alignment it gets given.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1231
This should remove some warnings from the CI, making it easier to see
legitimate CI failures.
For example, see https://gitlab.gnome.org/GNOME/glib/-/jobs/1621041.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
When an object with toggle reference is notifying a change we just
assume that this is true because of previous checks.
However, while locking, another thread may have removed the toggle
reference causing the waiting thread to abort (as no handler is set at
that point).
To avoid this, once we've got the toggle references mutex lock, check
again if the object has toggle reference, and if it's not the case
anymore just ignore the request.
Add a test that triggers this, it's not 100% happening because this is
of course timing related, but this is very close to the truth.
Fixes: #2394
The previous wording was not clear about what happens if a new weak ref
is taken during disposal (shortly after resurrecting the object with a
new strong ref, otherwise taking the weak ref is invalid).
See: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2064/diffs#note_1270092
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2390
No need to call memset in the loop, we can just
initialize all the values in one go.
GtkBuilder is now using g_object_setv, so this
may improve application start times a bit.