After a splice operation is finished, it attempts to 1) close input/output
streams, as per the given flags, and 2) return the operation result (maybe
an error, too).
However, if the operation gets cancelled early and the streams indirectly
closed, the splice operation will try to close both descriptors and return
on the task when both are already closed. The catch here is that getting the
streams closed under its feet is possible, so the completion callback would
find both streams closed after returning on the first close operation and
return the error, but then the second operation could be able to trigger
a second error which would be returned as well.
What happens here is up to further race conditions, if the task didn't
return yet, the returned error will be simply replaced (but the old one not
freed...), if it did already return, it'll result in:
GLib-GIO-FATAL-CRITICAL: g_task_return_error: assertion '!task->ever_returned' failed
Fix this by flagging the close_async() callbacks, and checking that both
close operations did return, instead of checking that both streams are
closed by who knows.
This error triggers a semi-frequent CI failure in tracker, see the summary at
https://gitlab.gnome.org/GNOME/tracker/-/issues/240
This was mostly machine generated with the following command:
```
codespell \
--builtin clear,rare,usage \
--skip './po/*' --skip './.git/*' --skip './NEWS*' \
--write-changes .
```
using the latest git version of `codespell` as per [these
instructions](https://github.com/codespell-project/codespell#user-content-updating).
Then I manually checked each change using `git add -p`, made a few
manual fixups and dropped a load of incorrect changes.
There are still some outdated or loaded terms used in GLib, mostly to do
with git branch terminology. They will need to be changed later as part
of a wider migration of git terminology.
If I’ve missed anything, please file an issue!
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If flush_async is deleted by a child class, then calling
g_output_stream_flush_async would leave the GOutputStream in an invalid
state. I'm not aware of any GOutputStream that would be affected by this
issue, but might as well fix it.
https://bugzilla.gnome.org/show_bug.cgi?id=738277
If we have an input parameter (or return value) we need to use (nullable).
However, if it is an (inout) or (out) parameter, (optional) is sufficient.
It looks like (nullable) could be used for everything according to the
Annotation documentation, but (optional) is more specific.
When G_OUTPUT_STREAM_CLOSE_TARGET is set,
g_output_stream_real_splice was not returning -1 in any error
cases, since the success flag was being overwritten.
https://bugzilla.gnome.org/show_bug.cgi?id=756255
Add an internal helper to find out if close_async() is implemented via
threads using the default implementation in the base class.
We will use this to decide if we should do a 'pure async' close of a
GIOStream or not.
https://bugzilla.gnome.org/show_bug.cgi?id=741630
These functions are inconsistent with our normal conventions in that
they set an output variable to a specified value, even in the case that
an error is thrown.
Document very clearly that this should be considered exceptional.
https://bugzilla.gnome.org/show_bug.cgi?id=737451
Similar to the previous patch, this commit contains a minor violation of
normal API conventions. See the explanation in the previous commit
message.
Heavily based on a patch from Ignacio Casal Quinteiro.
https://bugzilla.gnome.org/show_bug.cgi?id=737451
Usually async methods copy/ref its arguments so caller can
forget about them. g_file_replace_contents_async() and
g_output_stream_write_async() are exceptions.
https://bugzilla.gnome.org/show_bug.cgi?id=690525
Matthew Barnes noted this on IRC a few days ago. I just had this file
open for other reasons and decided to tweak the docs to make this trap
more clear.
https://bugzilla.gnome.org/show_bug.cgi?id=709301
There are some corner cases where using the sync version of read/write
in a thread could cause thread-safety issues. In these cases it's
possible to override the output stream's splice_async() function,
but for input streams one would need to do some acrobatics to
stay thread-safe. Alternatively, some implementations may not even
override their sync read/write functions.
This patch refactors the default splice_async() implementation to
call the sync read and write functions in a thread only when both
async versions are thread-based. When one or both are non-threaded,
it calls the virtual write_async() and read_async() functions of the
involved streams within the same thread.
https://bugzilla.gnome.org/show_bug.cgi?id=691581
Refactor g_output_stream_close_async() into itself and an internal
variant for potential use inside other operations (splice_async).
The internal version must be called between
g_output_stream_set_pending() and g_output_stream_clear_pending().
https://bugzilla.gnome.org/show_bug.cgi?id=691581
In implementing a better g_output_stream_splice_async() and possibly
other situtations it's helpful to know whether the output stream's
write function internally uses threads. If it and the input stream's
read async functions use threads, then the splice function could
spawn a single thread for better efficiency.
This patch adds a function to determine whether an output stream's
g_output_stream_write_async() function internally uses threads.
https://bugzilla.gnome.org/show_bug.cgi?id=691581
As it turns out, we have examples of internal functions called
type_name_get_private() in the wild (especially among older libraries),
so we need to use a name for the per-instance private data getter
function that hopefully won't conflict with anything.
Rather than doing a two step first-check-the-GAsyncResult-subtype-then-
check-the-tag, add a GAsyncResult-level method so that you can do them
both at once, simplifying the code for "short-circuit" async return
values where the vmethod never gets called.
https://bugzilla.gnome.org/show_bug.cgi?id=661767
Finish deprecating the "handle GSimpleAsyncResult errors in the
wrapper function" idiom (and protect against future GSimpleAsyncResult
deprecation warnings) by adding a "legacy" GAsyncResult method
to do it in those classes/methods where it had been traditionally
done.
(This applies only to wrapper methods; in cases where an _async
vmethod explicitly uses GSimpleAsyncResult, its corresponding _finish
vmethod still uses g_simple_async_result_propagate_error.)
https://bugzilla.gnome.org/show_bug.cgi?id=667375https://bugzilla.gnome.org/show_bug.cgi?id=661767
Originally, the standard idiom with GSimpleAsyncResult was to handle
all errors in the _finish wrapper function, so that vmethods only had
to deal with successful results. But this means that chaining up to a
parent _finish vmethod won't work correctly. Fix this by also checking
for errors in all the relevant vmethods. (We have to redundantly check
in both the vmethod and the wrapper to preserve compatibility.)
https://bugzilla.gnome.org/show_bug.cgi?id=667375https://bugzilla.gnome.org/show_bug.cgi?id=661767
Using a caller-supplied buffer for g_input_stream_read() doesn't
translate well to the semantics of many other languages, and using a
non-refcounted buffer for read_async() and write_async() makes it
impossible to manage the memory correctly currently in
garbage-collected languages.
Fix both of these issues by adding a new set of methods that work with
GBytes objects rather than plain buffers.
https://bugzilla.gnome.org/show_bug.cgi?id=671139
g_output_stream_write_async() was not initializing the newly-added
members of the WriteData structure, causing various problems.
Also, g_input_stream_read_async() was now leaking its cancellable. Fix
that as well.
https://bugzilla.gnome.org/show_bug.cgi?id=674612
If a GInputStream does not provide a read_async() implementation, but
does implement GPollableInputStream, then instead of doing
read-synchronously-in-a-thread, just use
g_pollable_input_stream_read_nonblocking() and
g_pollable_input_stream_create_source() to implement an async read in
the same thread. Similarly for GOutputStream.
Remove a bunch of existing read_async()/write_async() implementations
that are basically equivalent to the new fallback method.
https://bugzilla.gnome.org/show_bug.cgi?id=673997
After questioning the semantics of flush on IRC, it seemed necessary to
clarify what flushing is supposed to do. The Linux man page for fflush()
seemed to cover it perfectly, so I just copied it.
I did not add the "via the underlying write mechanism" part as that in
my opinion is not something subclasses should need to guarantee.
Ensure that the output/target stream in a g_output_stream_splice_async()
operation is marked as closed if G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET is
passed to g_output_stream_splice_async(). This removes the possibility of
local FDs being closed twice because the stream's not marked as closed.
This is implemented by calling g_output_stream_close() from within
g_output_stream_splice_async() instead of calling the stream's close_fn()
directly.
Closes: bgo#659324