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
This is a minor performance improvement, since the pspec list for the
class now only has to be modified once, rather than twice.
It also means we now have the `GParamSpec` pointers to hand in a `props`
array, which will be used in the upcoming commits.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
This lets the compiler tell us if we’ve accidentally missed a property
implementation from `get_property()` or `set_property()`.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
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.
The cancelled state may be set and read by different threads, so ensure
that it's stored and managed in an atomic way.
We could in fact end up check for `g_file_monitor_is_cancelled()` in a
thread and `g_file_monitor_cancel()` or `g_file_monitor_emit_event` in
in another one.
We were reusing the same logic everywhere, while we can just reuse an
unique class to base our tests on that avoids having to copy-and-paste
code for no good reason
Add some basic support for having glib-tests-only python libraries that
can be shared across the various projects, so that we don't have to
maintain multiple copies of them.
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
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.
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.
Let’s not go with SHOUTY UNIX or quiet unix, let’s just call it what
Wikipedia calls it (https://en.wikipedia.org/wiki/Unix).
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
They need a `GUnixMountMonitor` to give valid timestamps, and if you
have one of those then you might as well listen to its signals anyway.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3569
If only someone would go ahead and invent a whole section of the list of
HTTP status codes which could be used to inform a client of where a
document has been moved to.
For the sake of argument, let’s say it could be status codes 300–399,
since they appear to be completely unused at the moment.
😩
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
The documentation for GLib and Gio contains a number of documentation
comment blocks where a parameter reference (e.g. `@err`) is also
discussed in its dereferenced pointer form, which is generally
annotated as `*@err`. This inevitably confuses the MarkDown parser,
which sees the `*` as the beginning of an italicized text span.
To avoid this, replace all `*@foo` with <code>`*foo`</code>, which
loses the `@`-sigil linking it to the `@foo` parameter, but formats
correctly in the rendered documentation. (`@foo` is automatically
formatted like <code>`foo`</code>, so the resulting appearance in
the docs is as intended.)
`@filename@` expands to the (absolute or relative) path from the
build directory to the source directory, which can be rather verbose.
In practice Meson usually (always?) generates a relative path, but
even so, the resulting installed header is not necessarily reproducible
if using different build directories outside the source directory.
We don't really need a full path here anyway: the basename is enough
of a hint to point a reader towards the file where the underlying
enum was defined.
Signed-off-by: Simon McVittie <smcv@collabora.com>
As per the previous few commits, explicitly document the established
reference counting semantics of the method call closure for
`g_dbus_connection_register_object_with_closures()`.
This isn’t ideal, but
`g_dbus_connection_register_object_with_closures()` has had these
semantics for 10 years now, and it’s a bit late to change them to
something neater.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3559