The process PID is initialized by the initable vfunc, while
g_subprocess_exited sets it again, when we're protecting it via a lock.
The status is set when the process exits instead, again while locking.
This makes the thread sanitizer unhappy (even if it shouldn't really be
a race for the PID init case), but still locking during initialization is
not a bad thing to do.
At the same time g_subprocess_wait() and friends were using the pid and status
values without any protection, so let's ensure this is not the case anymore.
WARNING: ThreadSanitizer: data race (pid=8213)
Write of size 4 at 0x7b200000084c by thread T1:
#0 g_subprocess_exited ../gio/gsubprocess.c:284
#1 g_child_watch_dispatch ../glib/gmain.c:5963
#2 g_main_dispatch ../glib/gmain.c:3373
#3 g_main_context_dispatch_unlocked ../glib/gmain.c:4224
#4 g_main_context_iterate_unlocked ../glib/gmain.c:4289
#5 g_main_context_iteration ../glib/gmain.c:4354
#6 glib_worker_main ../glib/gmain.c:6553
#7 g_thread_proxy ../glib/gthread.c:892
Previous read of size 4 at 0x7b200000084c by main thread:
#0 g_subprocess_wait ../gio/gsubprocess.c:908
#1 g_subprocess_wait_check ../gio/gsubprocess.c:939
#2 end_element ../gio/glib-compile-resources.c:342
#3 emit_end_element ../glib/gmarkup.c:1045
#4 g_markup_parse_context_parse ../glib/gmarkup.c:1603
#5 parse_resource_file ../gio/glib-compile-resources.c:578
#6 main ../gio/glib-compile-resources.c:967
Location is heap block of size 120 at 0x7b2000000800 allocated by main
thread:
#0 calloc <null>
#1 g_malloc0 ../glib/gmem.c:133
#2 g_type_create_instance ../gobject/gtype.c:1933
#3 g_object_new_internal ../gobject/gobject.c:2621
#4 g_object_new_valist ../gobject/gobject.c:2960
#5 g_initable_new_valist ../gio/ginitable.c:245
#6 g_initable_new ../gio/ginitable.c:163
#7 g_subprocess_newv ../gio/gsubprocess.c:619
#8 g_subprocess_new ../gio/gsubprocess.c:590
#9 end_element ../gio/glib-compile-resources.c:334
#10 emit_end_element ../glib/gmarkup.c:1045
#11 g_markup_parse_context_parse ../glib/gmarkup.c:1603
#12 parse_resource_file ../gio/glib-compile-resources.c:578
#13 main ../gio/glib-compile-resources.c:967
Thread T1 'gmain' (tid=8228, running) created by main thread at:
#0 pthread_create <null>
#1 g_system_thread_new ../glib/gthread-posix.c:762
#2 g_thread_new_internal ../glib/gthread.c:996
#3 g_thread_new ../glib/gthread.c:949
#4 g_get_worker_context ../glib/gmain.c:6580
#5 initable_init ../gio/gsubprocess.c:443
#6 g_initable_init ../gio/ginitable.c:129
#7 g_initable_new_valist ../gio/ginitable.c:249
#8 g_initable_new ../gio/ginitable.c:163
#9 g_subprocess_newv ../gio/gsubprocess.c:619
#10 g_subprocess_new ../gio/gsubprocess.c:590
#11 end_element ../gio/glib-compile-resources.c:334
#12 emit_end_element ../glib/gmarkup.c:1045
#13 g_markup_parse_context_parse ../glib/gmarkup.c:1603
#14 parse_resource_file ../gio/glib-compile-resources.c:578
#15 main ../gio/glib-compile-resources.c:967
SUMMARY: ThreadSanitizer: data race ../gio/gsubprocess.c:284 in
g_subprocess_exited
======================================
WARNING: ThreadSanitizer: data race (pid=15959)
Read of size 4 at 0x7b200000084c by main thread:
#0 g_subprocess_wait ../gio/gsubprocess.c:913
#1 g_subprocess_wait_check ../gio/gsubprocess.c:944
#2 test_cat_utf8 ../gio/tests/gsubprocess.c:489
#3 test_case_run ../glib/gtestutils.c:3115
#4 g_test_run_suite_internal ../glib/gtestutils.c:3210
#5 g_test_run_suite_internal ../glib/gtestutils.c:3229
#6 g_test_run_suite ../glib/gtestutils.c:3310
#7 g_test_run ../glib/gtestutils.c:2379
#8 main ../gio/tests/gsubprocess.c:2266
Previous write of size 4 at 0x7b200000084c by thread T1:
#0 g_subprocess_exited ../gio/gsubprocess.c:284
#1 g_child_watch_dispatch ../glib/gmain.c:5963
#2 g_main_dispatch ../glib/gmain.c:3373
#3 g_main_context_dispatch_unlocked ../glib/gmain.c:4224
#4 g_main_context_iterate_unlocked ../glib/gmain.c:4289
#5 g_main_context_iteration ../glib/gmain.c:4354
#6 glib_worker_main ../glib/gmain.c:6553
#7 g_thread_proxy ../glib/gthread.c:892
We use flags in both locked paths and in public ones (to check if a
source is destroyed or running), but those checks are not using atomic
logic, thus they lead to races in various tests.
Fix them by adding a new private flag (so that the public one can still
be used as it used to, without having to use atomic APIs there) that is
now used to atomically change and read the values.
And this fixes various tests in thread sanitizer
As per previous commit we used atomic logic to handle the cancellation,
but that lead to a slightly different behavior because the file monitor
was then marked as cancelled before the vfunc implementation was called.
Use similar behavior now (by still relying on the atomic logic), by
marking the state as about-to-cancel as soon as we're starting the
cancellation (preventing other threads to cancel it), and eventually
fully marking it as cancelled.
Move the shebang line from the full Python path of the build
machine to the first Python on the path during runtime. Set
the shebang in the main meson.build file so that it can be
overridden in one place if needed.
Fixes: #3331
As gettext does:
* if C locale is used to set a value, set the untranslated value, i.e.
key=value and not key[C]=value;
* if C locale is used to get a value, return the untranslated value,
i.e. not the value from key[C]=value, if it ever exists, and do not
consider C as an undefined locale otherwise.
Fixes: #3578
Link to the toolchain requirements, which are kept up to date, rather
than duplicating them across multiple documents.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
This will warn if GLib is configured with a toolchain which doesn’t
support C11. We currently require C99. If nobody complains (as directed
by this warning) we will start to require C11 in the next unstable
release series (2.85).
See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3574#note_1859924
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Prevent to access to a disposed gsource in the GCancellable cancelled
signal callback.
Due to the fact that the signal is called in the same thread in which
the cancellable get cancelled, we may receive the callback just after
the GSource has been disposed or during its disposal.
To prevent this, let's pass to the signal a pointer to the source itself
and nullify atomically the first time we're calling a callback or
disposing it.
In case the dispose function wins the race, then the callback will just
do nothing, while the disposal will continue as expected.
In case the callback wins the race, during the concurrent disposal we'll
just wait for the callback to be completed, before returning the disposal
itself that will likely lead to freeing the GSource.
Closes: #3448
It finally happened: someone managed to keep a process alive long
enough, and using a single `GDBusConnection`, to overflow the
`last_serial` counter in the connection and send an invalid message with
serial of zero (which is disallowed by the D-Bus specification).
Avoid that happening in future by skipping serials of zero on overflow,
and wrapping straight back around to 1.
This looks a little more confusing than it is, because `last_serial` is
pre-incremented on use, so to skip zero, we explicitly set it to zero.
This is exactly what happens when the `GDBusConnection` is initialised
anyway.
I can’t think of a way to add a unit test for this — there is no way to
affect the value of `last_serial` except by sending messages (each one
increments it), and in order to get it to overflow by sending messages
at 1kHz, the test would have to run for 49 days.
Instead, I tested this manually by temporarily modifying
`GDBusConnection` to initialise `last_serial` to `G_MAXUINT32 - 3`, then
checked that the unit tests all still passed, and that the overflow code
was being executed.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3592
The registry backend uses a thread to monitor
registry changes and send notifications.
The state of this thread and structures used
for communicating with it are kept in the watch
variable.
The subscribe and unsubscribe functions might be
concurrently called from multiple threads and
need to communicate with the monitoring thread.
For this reason we need to synchronize the access
to the watch variable.
Generate a deprecation notice in the `--help` output for deprecated
options. This helps with the documentation of command line utilities.
Put the deprecation notice near the argument, to allow application
developers to add a notice on the deprecation on their own, and
explain what to use instead.
We don't allow unloading types, both static and dynamic, since 2013. The
code that deals with reference counting is mostly dead code, and makes
reasoning about the type system more complicated than necessary.
Since type classes and interfaces can only be instantiated, we introduce
explicit getter functions that create a GTypeClass or a GTypeInterface
vtable; the ref() and unref() API gets a "soft" deprecation (explicitly
not using `GOBJECT_DEPRECATED_IN_*` yet), to allow people to
progressively port their code.
A new header check is added for non-standard <sys/ucred.h>. Some platforms, like Linux, might support <sys/param.h>, <sys/mount.h>, and <fstab.h> but not this. Which can cause compilation to fail for gio/gunixmounts.c
This request brings support to the latest version of QNX software. _g_get_unix_mount_points (void) for getfsent() system also works on QNX. To avoid duplicating codes, it will be reused.