Mention that ready time being equal to the current time means the source
will fire immediately.
Related to https://gitlab.gnome.org/GNOME/glib/-/issues/3148
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Instead of tracking a "(guint,GSource*)" tuple in the "context->sources"
dictionary, only track pointers to the "source_id".
With this we use the GHashTable as Set (g_hash_table_add()), which is
optimized and avoids storing a separate value array.
It's simple enough to do, because there are literally 5 references to
"context->sources". It's easy to review those usages and reason that the
handling is correct.
While at it, in g_main_context_find_source_by_id() move the check for
SOURCE_DESTROYED() inside the lock. It's not obvious that doing this
without a lock was correct in every case. But doing the check with
a lock should be fast enough to not worry about whether it's absolutely
necessary.
We have g_int_hash()/g_int_equal(), which in practice might also work
with with pointers to unsigned integers. However, according to strict
interpretation of C, I think it is not valid to conflate the two.
Even if it were valid in all cases that we want to support, we should
still have separate g_uint_{hash,equal} functions (e.g. by just #define
them to their underlying g_int_{hash,equal} implementations).
Add instead internal hash/equal functions for guint.
Previously thread-pool-slow ran a single test which encoded a state
machine and polling timer to run 8 different sub-tests and check for
their exit conditions.
This was a bit ugly, and since the timer ran at 1s granularity, several
of the tests completed quite fast and then hang around for most of 1s
before finishing and moving to the next test.
Split the test functions up into separate GTest tests, and split the
state machine up between the test functions. All of the `GMainLoop`
handling is actually only needed for the `test_threadpool_idle_time()`
test.
This reduces the overall test runtime from 36s to 19s on my machine,
with 17s of that being spent in `test_threadpool_idle_time()`.
Signed-off-by: Philip Withnall <philip@tecnocode.co.uk>
Helps: #2810
This makes things a bit more maintainable, as there’s less global state
to worry about.
It introduces no functional changes.
Signed-off-by: Philip Withnall <philip@tecnocode.co.uk>
The race was already acknowledged in the code (via `last_failed`): the
thread pool starts dequeuing jobs as soon as it’s created, so it’s
dequeuing the sorted thread IDs while they’re still being enqueued and
sorted. This can lead to them being dequeued out of the expected order
if new thread IDs are enqueued out of order, which is possible because
they’re randomly generated.
The test tried to handle this by allowing one out-of-order dequeue, but
it looks like the race can race hard enough that multiple out-of-order
dequeues are possible.
Fix that by only starting to dequeue the jobs from the thread pool once
they’ve all been enqueued and put in a total order.
Signed-off-by: Philip Withnall <philip@tecnocode.co.uk>
Fixes: #2810
If the string of one log domain is contained in
another, it was printing both.
For example, if G_MESSAGES_DEBUG is "Gtkspecial",
it would also keep the logs of the "Gtk" domain
The weak symbol resolution doesn’t seem to work (see
https://gitlab.gnome.org/GNOME/glib/-/jobs/3265405):
```
Undefined symbols for architecture x86_64:
"___lsan_enable", referenced from:
_g_leak_sanitizer_is_supported in gutils.c.o
"___lsan_ignore_object", referenced from:
_g_ignore_leak in gquark.c.o
_g_ignore_leak in gthreadpool.c.o
_g_ignore_leak in gutils.c.o
_g_leak_sanitizer_is_supported in gutils.c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
See !3672
Signed-off-by: Philip Withnall <philip@tecnocode.co.uk>
GLib ignores various leaks that we don't consider as such (like the
default gio modules) via the LSAN public interface, however those cases
are always ignored when using a non-ASAN compiled glib is used by an
ASAN-compiled binary.
This makes all the GLib-related programs to fail because of false
positive leaks.
To avoid this, use the gcc extension for weak linking so that we can
control ASAN and LSAN only if the symbols they provide are actually
available at runtime.
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.
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).
The alt-digits are loaded from `nl_langinfo()` in a `GOnce` section,
which means `nl_langinfo()` is not re-queried after the process changes
locale (if that happens).
So, change the `GOnce` to a mutex and store the locale of the alt-digits
alongside them. This will introduce contention when calling
`format_number()` is called, but how often are multiple threads trying
to format dates at the same time?
If this does get highlighted as a performance problem, the other
approach I considered was a `GPrivate` struct containing all the
locale-specific cached data. That comes at the cost of using a
`GPrivate` slot (although that’s only particularly expensive on Windows,
and the locale code is quite different for Windows, so perhaps that
could be avoided entirely). It does mean that all locale printing could
be lock-free and still safely update cached data on a locale change.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
When calling `g_file_set_contents_full()` without
`G_FILE_SET_CONTENTS_CONSISTENT`, the file is written by opening it,
`write()`ing to it, then closing it.
This is fine as long as the file is not longer than the new content you
want to set its contents to. If it is, the last bit of the old content
remains, because `g_file_set_contents_full()` was missing an
`ftruncate()` call.
Fix that, and change the tests to catch truncation failures in future.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #3144
The Windows x64 ABI follows the LLP64 model, so unsigned long int is 32 bits
Fixes the following warnings when compiling for Windows x64:
../glib/gobject/gatomicarray.c:85:3: warning: cast to smaller integer type 'unsigned long' from 'gpointer' (aka 'void *') [-Wvoid-pointer-to-int-cast]
VALGRIND_MALLOCLIKE_BLOCK (mem, real_size - sizeof (GAtomicArrayMetadata),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../glib/glib/valgrind.h:6479:5: note: expanded from macro 'VALGRIND_MALLOCLIKE_BLOCK'
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../glib/glib/valgrind.h:203:15: note: expanded from macro 'VALGRIND_DO_CLIENT_REQUEST_STMT'
do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../glib/glib/valgrind.h:417:20: note: expanded from macro 'VALGRIND_DO_CLIENT_REQUEST_EXPR'
_zzq_args[1] = (unsigned long int)(_zzq_arg1); \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See https://bugs.kde.org/show_bug.cgi?id=427146
g_strv_builder_take() allows to transfer ownership of the passed in
string.
This can be useful to avoid additional allocations when using functions
that transfer ownership to the caller like g_strdup_printf().
The testcase uses g_strv_builder_take and g_strv_builder_add to demo
that calls can be mixed.
We were initializing a DWORD (unsigned 32 bit) with a constant
of bigger rank (G_MAXSIZE) on 64 bit systems.
Fixes the following warnings on CLang when compiling for x64:
../glib/glib/tests/win32.c:47:14: warning: implicit conversion from 'unsigned long long' to 'DWORD' (aka 'unsigned long') changes value from 18446744073709551615 to 4294967295 [-Wconstant-conversion]
DWORD bp = G_MAXSIZE;
~~ ^~~~~~~~~
glib/glibconfig.h:88:19: note: expanded from macro 'G_MAXSIZE'
#define G_MAXSIZE G_MAXUINT64
^~~~~~~~~~~
../glib/glib/gtypes.h:107:21: note: expanded from macro 'G_MAXUINT64'
#define G_MAXUINT64 G_GUINT64_CONSTANT(0xffffffffffffffff)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
glib/glibconfig.h:69:52: note: expanded from macro 'G_GUINT64_CONSTANT'
#define G_GUINT64_CONSTANT(val) (G_GNUC_EXTENSION (val##ULL))
^~~~~~~~
<scratch space>:96:1: note: expanded from here
0xffffffffffffffffULL
^~~~~~~~~~~~~~~~~~~~~
Many toolchain did not change the definition of NULL to avoid introducing
breaking changes in existing codebases. For example, on Windows NULL is
0 (int) regardless of the C++ standard in use.
Fixes the following warnings on CLang when compiling for Windows:
../glib/glib/tests/cxx.cpp:539:34: warning: missing sentinel in function call [-Wsentinel]
g_test_init (&argc, &argv, NULL);
^
, nullptr
../glib/glib/gtestutils.h:298:9: note: function has been explicitly marked sentinel here
void g_test_init (int *argc,
^
../glib/gio/tests/cxx.cpp:62:34: warning: missing sentinel in function call [-Wsentinel]
g_test_init (&argc, &argv, NULL);
^
, nullptr
../glib/glib/gtestutils.h:298:9: note: function has been explicitly marked sentinel here
void g_test_init (int *argc,
^