When the param specs are provided as an array
with g_object_class_install_properties, keep
a copy of that array around and use it for
looking up properties without the param spec
pool.
Note that this is an opportunistic optimization -
currently, it only works for properties of the
class itself, not for parent classes, and it
only works if the property names are identical
string literals (we're at the mercy of the linker
for that).
If we don't get lucky, we fall back to using
the pspec pool as usual.
Atomic APIs provide a way to exchange values only if we compare a value
that is equal to the old value, but not to just exchange the value
returning the old one.
However, compilers provide such built-in functions, so we can use them
to expose such functionality to GLib.
The only drawback is that when using an old version of gcc not providing
atomic APIs to swap values, we need to re-implement it with an
implementation that may not be fully atomic, but that is safe enough.
However this codepath should really not be used currently as gcc
introduced __atomic_exchange_n() at version 4.7.4, so 8 years ago.
`ptr_array_null_terminate()` only `NULL`-terminates the array if its
`null_terminated` flag is set; otherwise it’s a no-op.
Rename the function to `ptr_array_maybe_null_terminate()` to make that a
bit clearer, and make it consistent with `g_ptr_array_maybe_expand()`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This may fix Coverity assuming that pspecs are leaked, which is causing
tens and tens of false positives in the latest Coverity reports for
GLib.
Ensure that the pspecs are sunk (if floating) even if adding them to the
class fails (due to validation failure or an identically named property
already existing).
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Dynamically, all the right elements of `ps` are initialised before they
are used. However, scan-build doesn’t think so. It (probably) thinks
that `number_of_blocks` could change value between the different loops
over `ps`.
Try and avoid that by marking `number_of_blocks` (and related variables)
as `const`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
It seems that scan-build assumes `n_threads > 0`, but doesn’t assume a
tighter condition than that, and hence assumes that the two loops to
initialise and join the threads have different numbers of iterations.
That’s obviously not the case.
Try and help scan-build out here by marking `n_threads` as `const`. I
don’t know if this will work, but it’s correct regardless.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
scan-build can’t link the types used in `g_variant_builder_init()` with
the (same) types used in `g_variant_builder_end()`, so ends up assuming
that the children have not been initialised.
At runtime, this is prevented by the precondition checks on
`GVSB()->offset` in `g_variant_builder_end()`. scan-build doesn’t notice
that though.
Avoid a scan-build warning by zero-initialising the children array when
running static analysis. Doing this unconditionally would be an
unnecessary performance hit.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Recent changes to `GPtrArray` and/or Coverity mean that Coverity is now
assuming that `g_ptr_array_free (my_array, TRUE)` can leak memory. This
is true in the case that `g_ptr_array_ref (my_array)` has been called
elsewhere, but Coverity never actually verifies that.
Very little (or no?) GLib code mixes `g_ptr_array_free()` with
`g_ptr_array_{ref,unref}()`, so this isn’t a problem in practice.
However, it has created a hundred or more false positives in Coverity
(as pointer arrays are widely used within GLib and GIO), which is a
complete pain.
Before taking the dramatic step of ditching Coverity due to its
atrocious false positive rate, let’s try changing the semantics of
`g_ptr_array_free()` only when running under Coverity.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Dynamically, these will only ever be used after they’ve been initialised
due to correct checking of `use_udp` throughout the test. However,
that’s a global variable and the static analyser is assuming it might
change value. So help it out by NULL-initialising the variables so they
can never be used uninitialised.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
The code was accidentally NULL-terminating the source array rather than
the copy.
This fixes commit ee247c0a2d.
Spotted by the `array-test` installed test in
https://gitlab.gnome.org/GNOME/glib/-/jobs/2047993.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Valgrind has a limit of 500 threads (unless you pass `--max-threads` to
it). Running this test with more threads than that under valgrind seems
unnecessary, so reduce the thread limit when valgrind support is
enabled.
This should fix the following test failure:
```
Use --max-threads=INT to specify a larger number of threads
and rerun valgrind
valgrind: the 'impossible' happened:
Max number of threads is too low
host stacktrace:
==5239== at 0x580427EA: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==5239== by 0x58042917: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==5239== by 0x58042B80: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==5239== by 0x58042BB0: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==5239== by 0x58099C0E: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==5239== by 0x580E6839: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==5239== by 0x5809D3E9: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==5239== by 0x58098DB2: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==5239== by 0x5809AE97: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==5239== by 0x580E40B0: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable syscall 56 (lwpid 5239)
==5239== at 0x4AB0315: clone (in /usr/lib64/libc-2.33.so)
client stack range: [0x1FFEFFB000 0x1FFF000FFF] client SP: 0x1FFEFFC468
valgrind stack range: [0x1008BAA000 0x1008CA9FFF] top usage: 8776 of 1048576
Thread 2: status = VgTs_WaitSys syscall 202 (lwpid 5268)
==5239== at 0x4AAADDD: syscall (in /usr/lib64/libc-2.33.so)
==5239== by 0x491E2C2: g_mutex_lock_slowpath (gthread-posix.c:1495)
==5239== by 0x491E37C: g_mutex_lock (gthread-posix.c:1519)
==5239== by 0x491E489: g_cond_wait (gthread-posix.c:1578)
==5239== by 0x401436: once_thread_func (once.c:96)
==5239== by 0x48E9F31: g_thread_proxy (gthread.c:829)
==5239== by 0x491DE3A: linux_pthread_proxy (gthread-posix.c:1271)
==5239== by 0x4C002A4: start_thread (in /usr/lib64/libpthread-2.33.so)
==5239== by 0x4AB0322: clone (in /usr/lib64/libc-2.33.so)
client stack range: [0x5022000 0x5820FFF] client SP: 0x5820D28
valgrind stack range: [0x100B267000 0x100B366FFF] top usage: 3544 of 1048576
```
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1910
This reverts commit 0ddea2d8e2.
The commit was based on the misunderstanding that types
declared with G_DECLARE_FINAL_TYPE are actually non-derivable.
But that is only the case for types defined with
G_DEFINE_FINAL_TYPE.
Fixes: #2661
If we have no nontrivial notify vfunc, and no signal
handlers for notify, we don't need to maintain the
notify queue. No need to notify if nobody's listening.
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.