We used to do get and set atomic operations pair, but these may be
unsafe in some cases as threads may rely on data that is changed in
in between them, however this is not a problem if we do exchange the
pointers.
So just use exchange ops, in this way we can avoid lock/unlock mutex
dances
We can use pointer exchange now to avoid doing two operations to switch
to the new data pointer.
Since we're asserting in case of invalid data, we can just do this check
at later point, without involving any different behavior.
This changes in the unlikely case that G_DISABLE_ASSERT is defined, as in such
case we should undo the operation.
Clang seems to apply more rigorous type checks across the different
arguments to the atomic builtins. Fix various
`-Wincompatible-pointer-types`, `-Wpointer-sign` and `-Wint-conversion`
warnings.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This makes calls to g_signal_connect_data() and g_signal_connect_object()
with default flags more self-documenting.
Signed-off-by: Simon McVittie <smcv@collabora.com>
This makes code that sets no flags a bit more self-documenting:
using G_TYPE_FLAG_NONE makes it clearer that no special behaviour is
required than literal 0, and clearer that there is no weird casting
between types than (GTypeFlags) 0.
GTypeFlags and GTypeFundamentalFlags occupy the same namespace and the
same bitfield, so I intentionally haven't added
G_TYPE_FUNDAMENTAL_FLAGS_NONE.
Signed-off-by: Simon McVittie <smcv@collabora.com>
The references to gint and guint were copy/pasted from
g_atomic_int_exchange(), but what we want here is a gpointer, gintptr
or guintptr like the rest of the g_atomic_pointer_ family.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Atomic primitives allow to do conditional compare and exchange but also
to get the value that was previously stored in the atomic variable.
Now, we provided an exchange function that allows to do an exchange if
the atomic value matches an expected value but we had no way to know
at the same time what was the value in the atomic at the moment of the
exchange try, an this can be useful in case that the operation fails,
for example if the current value is still acceptable for us, allowing
to do a kind of "OR" check:
gint old_value;
gint valid_value = 222;
while (!g_atomic_pointer_compare_and_exchange_value (&atomic,
valid_value, 555,
&old_value)
{
if (old_value == 555 || old_value == 222)
valid_value = old_value;
}
Despite the name, the call was still doing blocking operations when
looking for app handlers via GAppInfo. Now it's possible to use fully
async calls.
Together with previous commit, the API is now fully async.
Despite the name, we still used blocking calls to get the default app
for URI, now that we have an async implementation of the API to get the
default implementation for URI scheme, we can remove the blocking calls.
We did not check whether this function worked before, so add a simple
test case for it, providing some test functions to make it possible to
reply the same behavior
In some cases (such as in our CI tests) we may not have any dbus session
set after launching, but we always assumed so.
In case we have not a session bus set, we only have to return early.
In both callbacks of g_file_query_default_handler_async() we were
actually using I/O blocking APIs making it not fully async.
Now that such API is provided, we can use it.
While it's possible to create a directory synchronously via
g_dir_make_tmp(), there's no such API that performs it asynchronously.
So implement it using GFile, using a thread to perform such task.
Avoid re defining cases for GIoErrorEnum when we already handle them
through GFileError, so remove code duplication and just rely on
g_file_error_from_errno() to compute the file error and then use
g_io_error_from_file_error() to get the possible IOError.
In case it's something not handled as GFileError, we can use the same
logic as before.
This is now a safe change to do as we have covered all the supported
cases in tests.