354c006b248d23ad1332e32dad437b5860c1a230
[platform/upstream/glib.git] / gio / goutputstream.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  *
18  * Author: Alexander Larsson <alexl@redhat.com>
19  */
20
21 #include "config.h"
22 #include <string.h>
23 #include "goutputstream.h"
24 #include "gcancellable.h"
25 #include "gasyncresult.h"
26 #include "gtask.h"
27 #include "ginputstream.h"
28 #include "gioerror.h"
29 #include "gioprivate.h"
30 #include "glibintl.h"
31 #include "gpollableoutputstream.h"
32
33 /**
34  * SECTION:goutputstream
35  * @short_description: Base class for implementing streaming output
36  * @include: gio/gio.h
37  *
38  * #GOutputStream has functions to write to a stream (g_output_stream_write()),
39  * to close a stream (g_output_stream_close()) and to flush pending writes
40  * (g_output_stream_flush()). 
41  *
42  * To copy the content of an input stream to an output stream without 
43  * manually handling the reads and writes, use g_output_stream_splice().
44  *
45  * See the documentation for #GIOStream for details of thread safety of
46  * streaming APIs.
47  *
48  * All of these functions have async variants too.
49  **/
50
51 struct _GOutputStreamPrivate {
52   guint closed : 1;
53   guint pending : 1;
54   guint closing : 1;
55   GAsyncReadyCallback outstanding_callback;
56 };
57
58 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GOutputStream, g_output_stream, G_TYPE_OBJECT)
59
60 static gssize   g_output_stream_real_splice        (GOutputStream             *stream,
61                                                     GInputStream              *source,
62                                                     GOutputStreamSpliceFlags   flags,
63                                                     GCancellable              *cancellable,
64                                                     GError                   **error);
65 static void     g_output_stream_real_write_async   (GOutputStream             *stream,
66                                                     const void                *buffer,
67                                                     gsize                      count,
68                                                     int                        io_priority,
69                                                     GCancellable              *cancellable,
70                                                     GAsyncReadyCallback        callback,
71                                                     gpointer                   data);
72 static gssize   g_output_stream_real_write_finish  (GOutputStream             *stream,
73                                                     GAsyncResult              *result,
74                                                     GError                   **error);
75 static void     g_output_stream_real_splice_async  (GOutputStream             *stream,
76                                                     GInputStream              *source,
77                                                     GOutputStreamSpliceFlags   flags,
78                                                     int                        io_priority,
79                                                     GCancellable              *cancellable,
80                                                     GAsyncReadyCallback        callback,
81                                                     gpointer                   data);
82 static gssize   g_output_stream_real_splice_finish (GOutputStream             *stream,
83                                                     GAsyncResult              *result,
84                                                     GError                   **error);
85 static void     g_output_stream_real_flush_async   (GOutputStream             *stream,
86                                                     int                        io_priority,
87                                                     GCancellable              *cancellable,
88                                                     GAsyncReadyCallback        callback,
89                                                     gpointer                   data);
90 static gboolean g_output_stream_real_flush_finish  (GOutputStream             *stream,
91                                                     GAsyncResult              *result,
92                                                     GError                   **error);
93 static void     g_output_stream_real_close_async   (GOutputStream             *stream,
94                                                     int                        io_priority,
95                                                     GCancellable              *cancellable,
96                                                     GAsyncReadyCallback        callback,
97                                                     gpointer                   data);
98 static gboolean g_output_stream_real_close_finish  (GOutputStream             *stream,
99                                                     GAsyncResult              *result,
100                                                     GError                   **error);
101 static gboolean g_output_stream_internal_close     (GOutputStream             *stream,
102                                                     GCancellable              *cancellable,
103                                                     GError                   **error);
104 static void     g_output_stream_internal_close_async (GOutputStream           *stream,
105                                                       int                      io_priority,
106                                                       GCancellable            *cancellable,
107                                                       GAsyncReadyCallback      callback,
108                                                       gpointer                 data);
109 static gboolean g_output_stream_internal_close_finish (GOutputStream          *stream,
110                                                        GAsyncResult           *result,
111                                                        GError                **error);
112
113 static void
114 g_output_stream_dispose (GObject *object)
115 {
116   GOutputStream *stream;
117
118   stream = G_OUTPUT_STREAM (object);
119   
120   if (!stream->priv->closed)
121     g_output_stream_close (stream, NULL, NULL);
122
123   G_OBJECT_CLASS (g_output_stream_parent_class)->dispose (object);
124 }
125
126 static void
127 g_output_stream_class_init (GOutputStreamClass *klass)
128 {
129   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
130
131   gobject_class->dispose = g_output_stream_dispose;
132
133   klass->splice = g_output_stream_real_splice;
134   
135   klass->write_async = g_output_stream_real_write_async;
136   klass->write_finish = g_output_stream_real_write_finish;
137   klass->splice_async = g_output_stream_real_splice_async;
138   klass->splice_finish = g_output_stream_real_splice_finish;
139   klass->flush_async = g_output_stream_real_flush_async;
140   klass->flush_finish = g_output_stream_real_flush_finish;
141   klass->close_async = g_output_stream_real_close_async;
142   klass->close_finish = g_output_stream_real_close_finish;
143 }
144
145 static void
146 g_output_stream_init (GOutputStream *stream)
147 {
148   stream->priv = g_output_stream_get_instance_private (stream);
149 }
150
151 /**
152  * g_output_stream_write:
153  * @stream: a #GOutputStream.
154  * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. 
155  * @count: the number of bytes to write
156  * @cancellable: (nullable): optional cancellable object
157  * @error: location to store the error occurring, or %NULL to ignore
158  *
159  * Tries to write @count bytes from @buffer into the stream. Will block
160  * during the operation.
161  * 
162  * If count is 0, returns 0 and does nothing. A value of @count
163  * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
164  *
165  * On success, the number of bytes written to the stream is returned.
166  * It is not an error if this is not the same as the requested size, as it
167  * can happen e.g. on a partial I/O error, or if there is not enough
168  * storage in the stream. All writes block until at least one byte
169  * is written or an error occurs; 0 is never returned (unless
170  * @count is 0).
171  * 
172  * If @cancellable is not %NULL, then the operation can be cancelled by
173  * triggering the cancellable object from another thread. If the operation
174  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
175  * operation was partially finished when the operation was cancelled the
176  * partial result will be returned, without an error.
177  *
178  * On error -1 is returned and @error is set accordingly.
179  * 
180  * Virtual: write_fn
181  *
182  * Returns: Number of bytes written, or -1 on error
183  **/
184 gssize
185 g_output_stream_write (GOutputStream  *stream,
186                        const void     *buffer,
187                        gsize           count,
188                        GCancellable   *cancellable,
189                        GError        **error)
190 {
191   GOutputStreamClass *class;
192   gssize res;
193
194   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
195   g_return_val_if_fail (buffer != NULL, 0);
196
197   if (count == 0)
198     return 0;
199   
200   if (((gssize) count) < 0)
201     {
202       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
203                    _("Too large count value passed to %s"), G_STRFUNC);
204       return -1;
205     }
206
207   class = G_OUTPUT_STREAM_GET_CLASS (stream);
208
209   if (class->write_fn == NULL) 
210     {
211       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
212                            _("Output stream doesn’t implement write"));
213       return -1;
214     }
215   
216   if (!g_output_stream_set_pending (stream, error))
217     return -1;
218   
219   if (cancellable)
220     g_cancellable_push_current (cancellable);
221   
222   res = class->write_fn (stream, buffer, count, cancellable, error);
223   
224   if (cancellable)
225     g_cancellable_pop_current (cancellable);
226   
227   g_output_stream_clear_pending (stream);
228
229   return res; 
230 }
231
232 /**
233  * g_output_stream_write_all:
234  * @stream: a #GOutputStream.
235  * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. 
236  * @count: the number of bytes to write
237  * @bytes_written: (out): location to store the number of bytes that was 
238  *     written to the stream
239  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
240  * @error: location to store the error occurring, or %NULL to ignore
241  *
242  * Tries to write @count bytes from @buffer into the stream. Will block
243  * during the operation.
244  * 
245  * This function is similar to g_output_stream_write(), except it tries to
246  * write as many bytes as requested, only stopping on an error.
247  *
248  * On a successful write of @count bytes, %TRUE is returned, and @bytes_written
249  * is set to @count.
250  * 
251  * If there is an error during the operation %FALSE is returned and @error
252  * is set to indicate the error status.
253  *
254  * As a special exception to the normal conventions for functions that
255  * use #GError, if this function returns %FALSE (and sets @error) then
256  * @bytes_written will be set to the number of bytes that were
257  * successfully written before the error was encountered.  This
258  * functionality is only available from C.  If you need it from another
259  * language then you must write your own loop around
260  * g_output_stream_write().
261  *
262  * Returns: %TRUE on success, %FALSE if there was an error
263  **/
264 gboolean
265 g_output_stream_write_all (GOutputStream  *stream,
266                            const void     *buffer,
267                            gsize           count,
268                            gsize          *bytes_written,
269                            GCancellable   *cancellable,
270                            GError        **error)
271 {
272   gsize _bytes_written;
273   gssize res;
274
275   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
276   g_return_val_if_fail (buffer != NULL, FALSE);
277
278   _bytes_written = 0;
279   while (_bytes_written < count)
280     {
281       res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written,
282                                    cancellable, error);
283       if (res == -1)
284         {
285           if (bytes_written)
286             *bytes_written = _bytes_written;
287           return FALSE;
288         }
289       
290       if (res == 0)
291         g_warning ("Write returned zero without error");
292
293       _bytes_written += res;
294     }
295   
296   if (bytes_written)
297     *bytes_written = _bytes_written;
298
299   return TRUE;
300 }
301
302 /**
303  * g_output_stream_printf:
304  * @stream: a #GOutputStream.
305  * @bytes_written: (out): location to store the number of bytes that was
306  *     written to the stream
307  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
308  * @error: location to store the error occurring, or %NULL to ignore
309  * @format: the format string. See the printf() documentation
310  * @...: the parameters to insert into the format string
311  *
312  * This is a utility function around g_output_stream_write_all(). It
313  * uses g_strdup_vprintf() to turn @format and @... into a string that
314  * is then written to @stream.
315  *
316  * See the documentation of g_output_stream_write_all() about the
317  * behavior of the actual write operation.
318  *
319  * Note that partial writes cannot be properly checked with this
320  * function due to the variable length of the written string, if you
321  * need precise control over partial write failures, you need to
322  * create you own printf()-like wrapper around g_output_stream_write()
323  * or g_output_stream_write_all().
324  *
325  * Since: 2.40
326  *
327  * Returns: %TRUE on success, %FALSE if there was an error
328  **/
329 gboolean
330 g_output_stream_printf (GOutputStream  *stream,
331                         gsize          *bytes_written,
332                         GCancellable   *cancellable,
333                         GError        **error,
334                         const gchar    *format,
335                         ...)
336 {
337   va_list  args;
338   gboolean success;
339
340   va_start (args, format);
341   success = g_output_stream_vprintf (stream, bytes_written, cancellable,
342                                      error, format, args);
343   va_end (args);
344
345   return success;
346 }
347
348 /**
349  * g_output_stream_vprintf:
350  * @stream: a #GOutputStream.
351  * @bytes_written: (out): location to store the number of bytes that was
352  *     written to the stream
353  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
354  * @error: location to store the error occurring, or %NULL to ignore
355  * @format: the format string. See the printf() documentation
356  * @args: the parameters to insert into the format string
357  *
358  * This is a utility function around g_output_stream_write_all(). It
359  * uses g_strdup_vprintf() to turn @format and @args into a string that
360  * is then written to @stream.
361  *
362  * See the documentation of g_output_stream_write_all() about the
363  * behavior of the actual write operation.
364  *
365  * Note that partial writes cannot be properly checked with this
366  * function due to the variable length of the written string, if you
367  * need precise control over partial write failures, you need to
368  * create you own printf()-like wrapper around g_output_stream_write()
369  * or g_output_stream_write_all().
370  *
371  * Since: 2.40
372  *
373  * Returns: %TRUE on success, %FALSE if there was an error
374  **/
375 gboolean
376 g_output_stream_vprintf (GOutputStream  *stream,
377                          gsize          *bytes_written,
378                          GCancellable   *cancellable,
379                          GError        **error,
380                          const gchar    *format,
381                          va_list         args)
382 {
383   gchar    *text;
384   gboolean  success;
385
386   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
387   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (stream), FALSE);
388   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
389   g_return_val_if_fail (format != NULL, FALSE);
390
391   text = g_strdup_vprintf (format, args);
392   success = g_output_stream_write_all (stream,
393                                        text, strlen (text),
394                                        bytes_written, cancellable, error);
395   g_free (text);
396
397   return success;
398 }
399
400 /**
401  * g_output_stream_write_bytes:
402  * @stream: a #GOutputStream.
403  * @bytes: the #GBytes to write
404  * @cancellable: (nullable): optional cancellable object
405  * @error: location to store the error occurring, or %NULL to ignore
406  *
407  * A wrapper function for g_output_stream_write() which takes a
408  * #GBytes as input.  This can be more convenient for use by language
409  * bindings or in other cases where the refcounted nature of #GBytes
410  * is helpful over a bare pointer interface.
411  *
412  * However, note that this function may still perform partial writes,
413  * just like g_output_stream_write().  If that occurs, to continue
414  * writing, you will need to create a new #GBytes containing just the
415  * remaining bytes, using g_bytes_new_from_bytes(). Passing the same
416  * #GBytes instance multiple times potentially can result in duplicated
417  * data in the output stream.
418  *
419  * Returns: Number of bytes written, or -1 on error
420  **/
421 gssize
422 g_output_stream_write_bytes (GOutputStream  *stream,
423                              GBytes         *bytes,
424                              GCancellable   *cancellable,
425                              GError        **error)
426 {
427   gsize size;
428   gconstpointer data;
429
430   data = g_bytes_get_data (bytes, &size);
431
432   return g_output_stream_write (stream,
433                                 data, size,
434                                 cancellable,
435                                 error);
436 }
437
438 /**
439  * g_output_stream_flush:
440  * @stream: a #GOutputStream.
441  * @cancellable: (nullable): optional cancellable object
442  * @error: location to store the error occurring, or %NULL to ignore
443  *
444  * Forces a write of all user-space buffered data for the given
445  * @stream. Will block during the operation. Closing the stream will
446  * implicitly cause a flush.
447  *
448  * This function is optional for inherited classes.
449  * 
450  * If @cancellable is not %NULL, then the operation can be cancelled by
451  * triggering the cancellable object from another thread. If the operation
452  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
453  *
454  * Returns: %TRUE on success, %FALSE on error
455  **/
456 gboolean
457 g_output_stream_flush (GOutputStream  *stream,
458                        GCancellable   *cancellable,
459                        GError        **error)
460 {
461   GOutputStreamClass *class;
462   gboolean res;
463
464   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
465
466   if (!g_output_stream_set_pending (stream, error))
467     return FALSE;
468   
469   class = G_OUTPUT_STREAM_GET_CLASS (stream);
470
471   res = TRUE;
472   if (class->flush)
473     {
474       if (cancellable)
475         g_cancellable_push_current (cancellable);
476       
477       res = class->flush (stream, cancellable, error);
478       
479       if (cancellable)
480         g_cancellable_pop_current (cancellable);
481     }
482   
483   g_output_stream_clear_pending (stream);
484
485   return res;
486 }
487
488 /**
489  * g_output_stream_splice:
490  * @stream: a #GOutputStream.
491  * @source: a #GInputStream.
492  * @flags: a set of #GOutputStreamSpliceFlags.
493  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
494  * @error: a #GError location to store the error occurring, or %NULL to
495  * ignore.
496  *
497  * Splices an input stream into an output stream.
498  *
499  * Returns: a #gssize containing the size of the data spliced, or
500  *     -1 if an error occurred. Note that if the number of bytes
501  *     spliced is greater than %G_MAXSSIZE, then that will be
502  *     returned, and there is no way to determine the actual number
503  *     of bytes spliced.
504  **/
505 gssize
506 g_output_stream_splice (GOutputStream             *stream,
507                         GInputStream              *source,
508                         GOutputStreamSpliceFlags   flags,
509                         GCancellable              *cancellable,
510                         GError                   **error)
511 {
512   GOutputStreamClass *class;
513   gssize bytes_copied;
514
515   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
516   g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1);
517
518   if (g_input_stream_is_closed (source))
519     {
520       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
521                            _("Source stream is already closed"));
522       return -1;
523     }
524
525   if (!g_output_stream_set_pending (stream, error))
526     return -1;
527
528   class = G_OUTPUT_STREAM_GET_CLASS (stream);
529
530   if (cancellable)
531     g_cancellable_push_current (cancellable);
532
533   bytes_copied = class->splice (stream, source, flags, cancellable, error);
534
535   if (cancellable)
536     g_cancellable_pop_current (cancellable);
537
538   g_output_stream_clear_pending (stream);
539
540   return bytes_copied;
541 }
542
543 static gssize
544 g_output_stream_real_splice (GOutputStream             *stream,
545                              GInputStream              *source,
546                              GOutputStreamSpliceFlags   flags,
547                              GCancellable              *cancellable,
548                              GError                   **error)
549 {
550   GOutputStreamClass *class = G_OUTPUT_STREAM_GET_CLASS (stream);
551   gssize n_read, n_written;
552   gsize bytes_copied;
553   char buffer[8192], *p;
554   gboolean res;
555
556   bytes_copied = 0;
557   if (class->write_fn == NULL)
558     {
559       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
560                            _("Output stream doesn’t implement write"));
561       res = FALSE;
562       goto notsupported;
563     }
564
565   res = TRUE;
566   do
567     {
568       n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error);
569       if (n_read == -1)
570         {
571           res = FALSE;
572           break;
573         }
574
575       if (n_read == 0)
576         break;
577
578       p = buffer;
579       while (n_read > 0)
580         {
581           n_written = class->write_fn (stream, p, n_read, cancellable, error);
582           if (n_written == -1)
583             {
584               res = FALSE;
585               break;
586             }
587
588           p += n_written;
589           n_read -= n_written;
590           bytes_copied += n_written;
591         }
592
593       if (bytes_copied > G_MAXSSIZE)
594         bytes_copied = G_MAXSSIZE;
595     }
596   while (res);
597
598  notsupported:
599   if (!res)
600     error = NULL; /* Ignore further errors */
601
602   if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
603     {
604       /* Don't care about errors in source here */
605       g_input_stream_close (source, cancellable, NULL);
606     }
607
608   if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
609     {
610       /* But write errors on close are bad! */
611       if (!g_output_stream_internal_close (stream, cancellable, error))
612         res = FALSE;
613     }
614
615   if (res)
616     return bytes_copied;
617
618   return -1;
619 }
620
621 /* Must always be called inside
622  * g_output_stream_set_pending()/g_output_stream_clear_pending(). */
623 static gboolean
624 g_output_stream_internal_close (GOutputStream  *stream,
625                                 GCancellable   *cancellable,
626                                 GError        **error)
627 {
628   GOutputStreamClass *class;
629   gboolean res;
630
631   if (stream->priv->closed)
632     return TRUE;
633
634   class = G_OUTPUT_STREAM_GET_CLASS (stream);
635
636   stream->priv->closing = TRUE;
637
638   if (cancellable)
639     g_cancellable_push_current (cancellable);
640
641   if (class->flush)
642     res = class->flush (stream, cancellable, error);
643   else
644     res = TRUE;
645
646   if (!res)
647     {
648       /* flushing caused the error that we want to return,
649        * but we still want to close the underlying stream if possible
650        */
651       if (class->close_fn)
652         class->close_fn (stream, cancellable, NULL);
653     }
654   else
655     {
656       res = TRUE;
657       if (class->close_fn)
658         res = class->close_fn (stream, cancellable, error);
659     }
660
661   if (cancellable)
662     g_cancellable_pop_current (cancellable);
663
664   stream->priv->closing = FALSE;
665   stream->priv->closed = TRUE;
666
667   return res;
668 }
669
670 /**
671  * g_output_stream_close:
672  * @stream: A #GOutputStream.
673  * @cancellable: (nullable): optional cancellable object
674  * @error: location to store the error occurring, or %NULL to ignore
675  *
676  * Closes the stream, releasing resources related to it.
677  *
678  * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
679  * Closing a stream multiple times will not return an error.
680  *
681  * Closing a stream will automatically flush any outstanding buffers in the
682  * stream.
683  *
684  * Streams will be automatically closed when the last reference
685  * is dropped, but you might want to call this function to make sure 
686  * resources are released as early as possible.
687  *
688  * Some streams might keep the backing store of the stream (e.g. a file descriptor)
689  * open after the stream is closed. See the documentation for the individual
690  * stream for details.
691  *
692  * On failure the first error that happened will be reported, but the close
693  * operation will finish as much as possible. A stream that failed to
694  * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it
695  * is important to check and report the error to the user, otherwise
696  * there might be a loss of data as all data might not be written.
697  * 
698  * If @cancellable is not %NULL, then the operation can be cancelled by
699  * triggering the cancellable object from another thread. If the operation
700  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
701  * Cancelling a close will still leave the stream closed, but there some streams
702  * can use a faster close that doesn't block to e.g. check errors. On
703  * cancellation (as with any error) there is no guarantee that all written
704  * data will reach the target. 
705  *
706  * Returns: %TRUE on success, %FALSE on failure
707  **/
708 gboolean
709 g_output_stream_close (GOutputStream  *stream,
710                        GCancellable   *cancellable,
711                        GError        **error)
712 {
713   gboolean res;
714
715   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
716
717   if (stream->priv->closed)
718     return TRUE;
719
720   if (!g_output_stream_set_pending (stream, error))
721     return FALSE;
722
723   res = g_output_stream_internal_close (stream, cancellable, error);
724
725   g_output_stream_clear_pending (stream);
726   
727   return res;
728 }
729
730 static void
731 async_ready_write_callback_wrapper (GObject      *source_object,
732                                     GAsyncResult *res,
733                                     gpointer      user_data)
734 {
735   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
736   GOutputStreamClass *class;
737   GTask *task = user_data;
738   gssize nwrote;
739   GError *error = NULL;
740
741   g_output_stream_clear_pending (stream);
742   
743   if (g_async_result_legacy_propagate_error (res, &error))
744     nwrote = -1;
745   else
746     {
747       class = G_OUTPUT_STREAM_GET_CLASS (stream);
748       nwrote = class->write_finish (stream, res, &error);
749     }
750
751   if (nwrote >= 0)
752     g_task_return_int (task, nwrote);
753   else
754     g_task_return_error (task, error);
755   g_object_unref (task);
756 }
757
758 /**
759  * g_output_stream_write_async:
760  * @stream: A #GOutputStream.
761  * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. 
762  * @count: the number of bytes to write
763  * @io_priority: the io priority of the request.
764  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
765  * @callback: (scope async): callback to call when the request is satisfied
766  * @user_data: (closure): the data to pass to callback function
767  *
768  * Request an asynchronous write of @count bytes from @buffer into 
769  * the stream. When the operation is finished @callback will be called.
770  * You can then call g_output_stream_write_finish() to get the result of the 
771  * operation.
772  *
773  * During an async request no other sync and async calls are allowed, 
774  * and will result in %G_IO_ERROR_PENDING errors. 
775  *
776  * A value of @count larger than %G_MAXSSIZE will cause a 
777  * %G_IO_ERROR_INVALID_ARGUMENT error.
778  *
779  * On success, the number of bytes written will be passed to the
780  * @callback. It is not an error if this is not the same as the 
781  * requested size, as it can happen e.g. on a partial I/O error, 
782  * but generally we try to write as many bytes as requested. 
783  *
784  * You are guaranteed that this method will never fail with
785  * %G_IO_ERROR_WOULD_BLOCK - if @stream can't accept more data, the
786  * method will just wait until this changes.
787  *
788  * Any outstanding I/O request with higher priority (lower numerical 
789  * value) will be executed before an outstanding request with lower 
790  * priority. Default priority is %G_PRIORITY_DEFAULT.
791  *
792  * The asynchronous methods have a default fallback that uses threads
793  * to implement asynchronicity, so they are optional for inheriting 
794  * classes. However, if you override one you must override all.
795  *
796  * For the synchronous, blocking version of this function, see 
797  * g_output_stream_write().
798  *
799  * Note that no copy of @buffer will be made, so it must stay valid
800  * until @callback is called. See g_output_stream_write_bytes_async()
801  * for a #GBytes version that will automatically hold a reference to
802  * the contents (without copying) for the duration of the call.
803  */
804 void
805 g_output_stream_write_async (GOutputStream       *stream,
806                              const void          *buffer,
807                              gsize                count,
808                              int                  io_priority,
809                              GCancellable        *cancellable,
810                              GAsyncReadyCallback  callback,
811                              gpointer             user_data)
812 {
813   GOutputStreamClass *class;
814   GError *error = NULL;
815   GTask *task;
816
817   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
818   g_return_if_fail (buffer != NULL);
819
820   task = g_task_new (stream, cancellable, callback, user_data);
821   g_task_set_source_tag (task, g_output_stream_write_async);
822   g_task_set_priority (task, io_priority);
823
824   if (count == 0)
825     {
826       g_task_return_int (task, 0);
827       g_object_unref (task);
828       return;
829     }
830
831   if (((gssize) count) < 0)
832     {
833       g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
834                                _("Too large count value passed to %s"),
835                                G_STRFUNC);
836       g_object_unref (task);
837       return;
838     }
839
840   if (!g_output_stream_set_pending (stream, &error))
841     {
842       g_task_return_error (task, error);
843       g_object_unref (task);
844       return;
845     }
846   
847   class = G_OUTPUT_STREAM_GET_CLASS (stream);
848
849   class->write_async (stream, buffer, count, io_priority, cancellable,
850                       async_ready_write_callback_wrapper, task);
851 }
852
853 /**
854  * g_output_stream_write_finish:
855  * @stream: a #GOutputStream.
856  * @result: a #GAsyncResult.
857  * @error: a #GError location to store the error occurring, or %NULL to 
858  * ignore.
859  * 
860  * Finishes a stream write operation.
861  * 
862  * Returns: a #gssize containing the number of bytes written to the stream.
863  **/
864 gssize
865 g_output_stream_write_finish (GOutputStream  *stream,
866                               GAsyncResult   *result,
867                               GError        **error)
868 {
869   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
870   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
871   g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_write_async), FALSE);
872
873   /* @result is always the GTask created by g_output_stream_write_async();
874    * we called class->write_finish() from async_ready_write_callback_wrapper.
875    */
876   return g_task_propagate_int (G_TASK (result), error);
877 }
878
879 typedef struct
880 {
881   const guint8 *buffer;
882   gsize to_write;
883   gsize bytes_written;
884 } AsyncWriteAll;
885
886 static void
887 free_async_write_all (gpointer data)
888 {
889   g_slice_free (AsyncWriteAll, data);
890 }
891
892 static void
893 write_all_callback (GObject      *stream,
894                     GAsyncResult *result,
895                     gpointer      user_data)
896 {
897   GTask *task = user_data;
898   AsyncWriteAll *data = g_task_get_task_data (task);
899
900   if (result)
901     {
902       GError *error = NULL;
903       gssize nwritten;
904
905       nwritten = g_output_stream_write_finish (G_OUTPUT_STREAM (stream), result, &error);
906
907       if (nwritten == -1)
908         {
909           g_task_return_error (task, error);
910           g_object_unref (task);
911           return;
912         }
913
914       g_assert_cmpint (nwritten, <=, data->to_write);
915       g_warn_if_fail (nwritten > 0);
916
917       data->to_write -= nwritten;
918       data->bytes_written += nwritten;
919     }
920
921   if (data->to_write == 0)
922     {
923       g_task_return_boolean (task, TRUE);
924       g_object_unref (task);
925     }
926
927   else
928     g_output_stream_write_async (G_OUTPUT_STREAM (stream),
929                                  data->buffer + data->bytes_written,
930                                  data->to_write,
931                                  g_task_get_priority (task),
932                                  g_task_get_cancellable (task),
933                                  write_all_callback, task);
934 }
935
936 static void
937 write_all_async_thread (GTask        *task,
938                         gpointer      source_object,
939                         gpointer      task_data,
940                         GCancellable *cancellable)
941 {
942   GOutputStream *stream = source_object;
943   AsyncWriteAll *data = task_data;
944   GError *error = NULL;
945
946   if (g_output_stream_write_all (stream, data->buffer, data->to_write, &data->bytes_written,
947                                  g_task_get_cancellable (task), &error))
948     g_task_return_boolean (task, TRUE);
949   else
950     g_task_return_error (task, error);
951 }
952
953 /**
954  * g_output_stream_write_all_async:
955  * @stream: A #GOutputStream
956  * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write
957  * @count: the number of bytes to write
958  * @io_priority: the io priority of the request
959  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
960  * @callback: (scope async): callback to call when the request is satisfied
961  * @user_data: (closure): the data to pass to callback function
962  *
963  * Request an asynchronous write of @count bytes from @buffer into
964  * the stream. When the operation is finished @callback will be called.
965  * You can then call g_output_stream_write_all_finish() to get the result of the
966  * operation.
967  *
968  * This is the asynchronous version of g_output_stream_write_all().
969  *
970  * Call g_output_stream_write_all_finish() to collect the result.
971  *
972  * Any outstanding I/O request with higher priority (lower numerical
973  * value) will be executed before an outstanding request with lower
974  * priority. Default priority is %G_PRIORITY_DEFAULT.
975  *
976  * Note that no copy of @buffer will be made, so it must stay valid
977  * until @callback is called.
978  *
979  * Since: 2.44
980  */
981 void
982 g_output_stream_write_all_async (GOutputStream       *stream,
983                                  const void          *buffer,
984                                  gsize                count,
985                                  int                  io_priority,
986                                  GCancellable        *cancellable,
987                                  GAsyncReadyCallback  callback,
988                                  gpointer             user_data)
989 {
990   AsyncWriteAll *data;
991   GTask *task;
992
993   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
994   g_return_if_fail (buffer != NULL || count == 0);
995
996   task = g_task_new (stream, cancellable, callback, user_data);
997   data = g_slice_new0 (AsyncWriteAll);
998   data->buffer = buffer;
999   data->to_write = count;
1000
1001   g_task_set_source_tag (task, g_output_stream_write_all_async);
1002   g_task_set_task_data (task, data, free_async_write_all);
1003   g_task_set_priority (task, io_priority);
1004
1005   /* If async writes are going to be handled via the threadpool anyway
1006    * then we may as well do it with a single dispatch instead of
1007    * bouncing in and out.
1008    */
1009   if (g_output_stream_async_write_is_via_threads (stream))
1010     {
1011       g_task_run_in_thread (task, write_all_async_thread);
1012       g_object_unref (task);
1013     }
1014   else
1015     write_all_callback (G_OBJECT (stream), NULL, task);
1016 }
1017
1018 /**
1019  * g_output_stream_write_all_finish:
1020  * @stream: a #GOutputStream
1021  * @result: a #GAsyncResult
1022  * @bytes_written: (out): location to store the number of bytes that was written to the stream
1023  * @error: a #GError location to store the error occurring, or %NULL to ignore.
1024  *
1025  * Finishes an asynchronous stream write operation started with
1026  * g_output_stream_write_all_async().
1027  *
1028  * As a special exception to the normal conventions for functions that
1029  * use #GError, if this function returns %FALSE (and sets @error) then
1030  * @bytes_written will be set to the number of bytes that were
1031  * successfully written before the error was encountered.  This
1032  * functionality is only available from C.  If you need it from another
1033  * language then you must write your own loop around
1034  * g_output_stream_write_async().
1035  *
1036  * Returns: %TRUE on success, %FALSE if there was an error
1037  *
1038  * Since: 2.44
1039  **/
1040 gboolean
1041 g_output_stream_write_all_finish (GOutputStream  *stream,
1042                                   GAsyncResult   *result,
1043                                   gsize          *bytes_written,
1044                                   GError        **error)
1045 {
1046   GTask *task;
1047
1048   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1049   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1050
1051   task = G_TASK (result);
1052
1053   if (bytes_written)
1054     {
1055       AsyncWriteAll *data = (AsyncWriteAll *)g_task_get_task_data (task);
1056
1057       *bytes_written = data->bytes_written;
1058     }
1059
1060   return g_task_propagate_boolean (task, error);
1061 }
1062
1063 static void
1064 write_bytes_callback (GObject      *stream,
1065                       GAsyncResult *result,
1066                       gpointer      user_data)
1067 {
1068   GTask *task = user_data;
1069   GError *error = NULL;
1070   gssize nwrote;
1071
1072   nwrote = g_output_stream_write_finish (G_OUTPUT_STREAM (stream),
1073                                          result, &error);
1074   if (nwrote == -1)
1075     g_task_return_error (task, error);
1076   else
1077     g_task_return_int (task, nwrote);
1078   g_object_unref (task);
1079 }
1080
1081 /**
1082  * g_output_stream_write_bytes_async:
1083  * @stream: A #GOutputStream.
1084  * @bytes: The bytes to write
1085  * @io_priority: the io priority of the request.
1086  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
1087  * @callback: (scope async): callback to call when the request is satisfied
1088  * @user_data: (closure): the data to pass to callback function
1089  *
1090  * This function is similar to g_output_stream_write_async(), but
1091  * takes a #GBytes as input.  Due to the refcounted nature of #GBytes,
1092  * this allows the stream to avoid taking a copy of the data.
1093  *
1094  * However, note that this function may still perform partial writes,
1095  * just like g_output_stream_write_async(). If that occurs, to continue
1096  * writing, you will need to create a new #GBytes containing just the
1097  * remaining bytes, using g_bytes_new_from_bytes(). Passing the same
1098  * #GBytes instance multiple times potentially can result in duplicated
1099  * data in the output stream.
1100  *
1101  * For the synchronous, blocking version of this function, see
1102  * g_output_stream_write_bytes().
1103  **/
1104 void
1105 g_output_stream_write_bytes_async (GOutputStream       *stream,
1106                                    GBytes              *bytes,
1107                                    int                  io_priority,
1108                                    GCancellable        *cancellable,
1109                                    GAsyncReadyCallback  callback,
1110                                    gpointer             user_data)
1111 {
1112   GTask *task;
1113   gsize size;
1114   gconstpointer data;
1115
1116   data = g_bytes_get_data (bytes, &size);
1117
1118   task = g_task_new (stream, cancellable, callback, user_data);
1119   g_task_set_source_tag (task, g_output_stream_write_bytes_async);
1120   g_task_set_task_data (task, g_bytes_ref (bytes),
1121                         (GDestroyNotify) g_bytes_unref);
1122
1123   g_output_stream_write_async (stream,
1124                                data, size,
1125                                io_priority,
1126                                cancellable,
1127                                write_bytes_callback,
1128                                task);
1129 }
1130
1131 /**
1132  * g_output_stream_write_bytes_finish:
1133  * @stream: a #GOutputStream.
1134  * @result: a #GAsyncResult.
1135  * @error: a #GError location to store the error occurring, or %NULL to
1136  * ignore.
1137  *
1138  * Finishes a stream write-from-#GBytes operation.
1139  *
1140  * Returns: a #gssize containing the number of bytes written to the stream.
1141  **/
1142 gssize
1143 g_output_stream_write_bytes_finish (GOutputStream  *stream,
1144                                     GAsyncResult   *result,
1145                                     GError        **error)
1146 {
1147   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
1148   g_return_val_if_fail (g_task_is_valid (result, stream), -1);
1149
1150   return g_task_propagate_int (G_TASK (result), error);
1151 }
1152
1153 static void
1154 async_ready_splice_callback_wrapper (GObject      *source_object,
1155                                      GAsyncResult *res,
1156                                      gpointer     _data)
1157 {
1158   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1159   GOutputStreamClass *class;
1160   GTask *task = _data;
1161   gssize nspliced;
1162   GError *error = NULL;
1163
1164   g_output_stream_clear_pending (stream);
1165   
1166   if (g_async_result_legacy_propagate_error (res, &error))
1167     nspliced = -1;
1168   else
1169     {
1170       class = G_OUTPUT_STREAM_GET_CLASS (stream);
1171       nspliced = class->splice_finish (stream, res, &error);
1172     }
1173
1174   if (nspliced >= 0)
1175     g_task_return_int (task, nspliced);
1176   else
1177     g_task_return_error (task, error);
1178   g_object_unref (task);
1179 }
1180
1181 /**
1182  * g_output_stream_splice_async:
1183  * @stream: a #GOutputStream.
1184  * @source: a #GInputStream. 
1185  * @flags: a set of #GOutputStreamSpliceFlags.
1186  * @io_priority: the io priority of the request.
1187  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. 
1188  * @callback: (scope async): a #GAsyncReadyCallback. 
1189  * @user_data: (closure): user data passed to @callback.
1190  * 
1191  * Splices a stream asynchronously.
1192  * When the operation is finished @callback will be called.
1193  * You can then call g_output_stream_splice_finish() to get the 
1194  * result of the operation.
1195  *
1196  * For the synchronous, blocking version of this function, see 
1197  * g_output_stream_splice().
1198  **/
1199 void
1200 g_output_stream_splice_async (GOutputStream            *stream,
1201                               GInputStream             *source,
1202                               GOutputStreamSpliceFlags  flags,
1203                               int                       io_priority,
1204                               GCancellable             *cancellable,
1205                               GAsyncReadyCallback       callback,
1206                               gpointer                  user_data)
1207 {
1208   GOutputStreamClass *class;
1209   GTask *task;
1210   GError *error = NULL;
1211
1212   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1213   g_return_if_fail (G_IS_INPUT_STREAM (source));
1214
1215   task = g_task_new (stream, cancellable, callback, user_data);
1216   g_task_set_source_tag (task, g_output_stream_splice_async);
1217   g_task_set_priority (task, io_priority);
1218   g_task_set_task_data (task, g_object_ref (source), g_object_unref);
1219
1220   if (g_input_stream_is_closed (source))
1221     {
1222       g_task_return_new_error (task,
1223                                G_IO_ERROR, G_IO_ERROR_CLOSED,
1224                                _("Source stream is already closed"));
1225       g_object_unref (task);
1226       return;
1227     }
1228   
1229   if (!g_output_stream_set_pending (stream, &error))
1230     {
1231       g_task_return_error (task, error);
1232       g_object_unref (task);
1233       return;
1234     }
1235
1236   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1237
1238   class->splice_async (stream, source, flags, io_priority, cancellable,
1239                        async_ready_splice_callback_wrapper, task);
1240 }
1241
1242 /**
1243  * g_output_stream_splice_finish:
1244  * @stream: a #GOutputStream.
1245  * @result: a #GAsyncResult.
1246  * @error: a #GError location to store the error occurring, or %NULL to 
1247  * ignore.
1248  *
1249  * Finishes an asynchronous stream splice operation.
1250  * 
1251  * Returns: a #gssize of the number of bytes spliced. Note that if the
1252  *     number of bytes spliced is greater than %G_MAXSSIZE, then that
1253  *     will be returned, and there is no way to determine the actual
1254  *     number of bytes spliced.
1255  **/
1256 gssize
1257 g_output_stream_splice_finish (GOutputStream  *stream,
1258                                GAsyncResult   *result,
1259                                GError        **error)
1260 {
1261   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1262   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1263   g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_splice_async), FALSE);
1264
1265   /* @result is always the GTask created by g_output_stream_splice_async();
1266    * we called class->splice_finish() from async_ready_splice_callback_wrapper.
1267    */
1268   return g_task_propagate_int (G_TASK (result), error);
1269 }
1270
1271 static void
1272 async_ready_flush_callback_wrapper (GObject      *source_object,
1273                                     GAsyncResult *res,
1274                                     gpointer      user_data)
1275 {
1276   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1277   GOutputStreamClass *class;
1278   GTask *task = user_data;
1279   gboolean flushed;
1280   GError *error = NULL;
1281
1282   g_output_stream_clear_pending (stream);
1283   
1284   if (g_async_result_legacy_propagate_error (res, &error))
1285     flushed = FALSE;
1286   else
1287     {
1288       class = G_OUTPUT_STREAM_GET_CLASS (stream);
1289       flushed = class->flush_finish (stream, res, &error);
1290     }
1291
1292   if (flushed)
1293     g_task_return_boolean (task, TRUE);
1294   else
1295     g_task_return_error (task, error);
1296   g_object_unref (task);
1297 }
1298
1299 /**
1300  * g_output_stream_flush_async:
1301  * @stream: a #GOutputStream.
1302  * @io_priority: the io priority of the request.
1303  * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
1304  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
1305  * @user_data: (closure): the data to pass to callback function
1306  * 
1307  * Forces an asynchronous write of all user-space buffered data for
1308  * the given @stream.
1309  * For behaviour details see g_output_stream_flush().
1310  *
1311  * When the operation is finished @callback will be 
1312  * called. You can then call g_output_stream_flush_finish() to get the 
1313  * result of the operation.
1314  **/
1315 void
1316 g_output_stream_flush_async (GOutputStream       *stream,
1317                              int                  io_priority,
1318                              GCancellable        *cancellable,
1319                              GAsyncReadyCallback  callback,
1320                              gpointer             user_data)
1321 {
1322   GOutputStreamClass *class;
1323   GTask *task;
1324   GError *error = NULL;
1325
1326   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1327
1328   task = g_task_new (stream, cancellable, callback, user_data);
1329   g_task_set_source_tag (task, g_output_stream_flush_async);
1330   g_task_set_priority (task, io_priority);
1331
1332   if (!g_output_stream_set_pending (stream, &error))
1333     {
1334       g_task_return_error (task, error);
1335       g_object_unref (task);
1336       return;
1337     }
1338
1339   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1340   
1341   if (class->flush_async == NULL)
1342     {
1343       g_task_return_boolean (task, TRUE);
1344       g_object_unref (task);
1345       return;
1346     }
1347       
1348   class->flush_async (stream, io_priority, cancellable,
1349                       async_ready_flush_callback_wrapper, task);
1350 }
1351
1352 /**
1353  * g_output_stream_flush_finish:
1354  * @stream: a #GOutputStream.
1355  * @result: a GAsyncResult.
1356  * @error: a #GError location to store the error occurring, or %NULL to 
1357  * ignore.
1358  * 
1359  * Finishes flushing an output stream.
1360  * 
1361  * Returns: %TRUE if flush operation succeeded, %FALSE otherwise.
1362  **/
1363 gboolean
1364 g_output_stream_flush_finish (GOutputStream  *stream,
1365                               GAsyncResult   *result,
1366                               GError        **error)
1367 {
1368   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1369   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1370   g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_flush_async), FALSE);
1371
1372   /* @result is always the GTask created by g_output_stream_flush_async();
1373    * we called class->flush_finish() from async_ready_flush_callback_wrapper.
1374    */
1375   return g_task_propagate_boolean (G_TASK (result), error);
1376 }
1377
1378
1379 static void
1380 async_ready_close_callback_wrapper (GObject      *source_object,
1381                                     GAsyncResult *res,
1382                                     gpointer      user_data)
1383 {
1384   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1385   GOutputStreamClass *class;
1386   GTask *task = user_data;
1387   GError *error = g_task_get_task_data (task);
1388
1389   stream->priv->closing = FALSE;
1390   stream->priv->closed = TRUE;
1391
1392   if (!error && !g_async_result_legacy_propagate_error (res, &error))
1393     {
1394       class = G_OUTPUT_STREAM_GET_CLASS (stream);
1395
1396       class->close_finish (stream, res,
1397                            error ? NULL : &error);
1398     }
1399
1400   if (error != NULL)
1401     g_task_return_error (task, error);
1402   else
1403     g_task_return_boolean (task, TRUE);
1404   g_object_unref (task);
1405 }
1406
1407 static void
1408 async_ready_close_flushed_callback_wrapper (GObject      *source_object,
1409                                             GAsyncResult *res,
1410                                             gpointer      user_data)
1411 {
1412   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1413   GOutputStreamClass *class;
1414   GTask *task = user_data;
1415   GError *error = NULL;
1416
1417   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1418
1419   if (!g_async_result_legacy_propagate_error (res, &error))
1420     {
1421       class->flush_finish (stream, res, &error);
1422     }
1423
1424   /* propagate the possible error */
1425   if (error)
1426     g_task_set_task_data (task, error, NULL);
1427
1428   /* we still close, even if there was a flush error */
1429   class->close_async (stream,
1430                       g_task_get_priority (task),
1431                       g_task_get_cancellable (task),
1432                       async_ready_close_callback_wrapper, task);
1433 }
1434
1435 static void
1436 real_close_async_cb (GObject      *source_object,
1437                      GAsyncResult *res,
1438                      gpointer      user_data)
1439 {
1440   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1441   GTask *task = user_data;
1442   GError *error = NULL;
1443   gboolean ret;
1444
1445   g_output_stream_clear_pending (stream);
1446
1447   ret = g_output_stream_internal_close_finish (stream, res, &error);
1448
1449   if (error != NULL)
1450     g_task_return_error (task, error);
1451   else
1452     g_task_return_boolean (task, ret);
1453
1454   g_object_unref (task);
1455 }
1456
1457 /**
1458  * g_output_stream_close_async:
1459  * @stream: A #GOutputStream.
1460  * @io_priority: the io priority of the request.
1461  * @cancellable: (nullable): optional cancellable object
1462  * @callback: (scope async): callback to call when the request is satisfied
1463  * @user_data: (closure): the data to pass to callback function
1464  *
1465  * Requests an asynchronous close of the stream, releasing resources 
1466  * related to it. When the operation is finished @callback will be 
1467  * called. You can then call g_output_stream_close_finish() to get 
1468  * the result of the operation.
1469  *
1470  * For behaviour details see g_output_stream_close().
1471  *
1472  * The asynchronous methods have a default fallback that uses threads
1473  * to implement asynchronicity, so they are optional for inheriting 
1474  * classes. However, if you override one you must override all.
1475  **/
1476 void
1477 g_output_stream_close_async (GOutputStream       *stream,
1478                              int                  io_priority,
1479                              GCancellable        *cancellable,
1480                              GAsyncReadyCallback  callback,
1481                              gpointer             user_data)
1482 {
1483   GTask *task;
1484   GError *error = NULL;
1485
1486   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1487   
1488   task = g_task_new (stream, cancellable, callback, user_data);
1489   g_task_set_source_tag (task, g_output_stream_close_async);
1490   g_task_set_priority (task, io_priority);
1491
1492   if (!g_output_stream_set_pending (stream, &error))
1493     {
1494       g_task_return_error (task, error);
1495       g_object_unref (task);
1496       return;
1497     }
1498
1499   g_output_stream_internal_close_async (stream, io_priority, cancellable,
1500                                         real_close_async_cb, task);
1501 }
1502
1503 /* Must always be called inside
1504  * g_output_stream_set_pending()/g_output_stream_clear_pending().
1505  */
1506 void
1507 g_output_stream_internal_close_async (GOutputStream       *stream,
1508                                       int                  io_priority,
1509                                       GCancellable        *cancellable,
1510                                       GAsyncReadyCallback  callback,
1511                                       gpointer             user_data)
1512 {
1513   GOutputStreamClass *class;
1514   GTask *task;
1515
1516   task = g_task_new (stream, cancellable, callback, user_data);
1517   g_task_set_source_tag (task, g_output_stream_internal_close_async);
1518   g_task_set_priority (task, io_priority);
1519
1520   if (stream->priv->closed)
1521     {
1522       g_task_return_boolean (task, TRUE);
1523       g_object_unref (task);
1524       return;
1525     }
1526
1527   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1528   stream->priv->closing = TRUE;
1529
1530   /* Call close_async directly if there is no need to flush, or if the flush
1531      can be done sync (in the output stream async close thread) */
1532   if (class->flush_async == NULL ||
1533       (class->flush_async == g_output_stream_real_flush_async &&
1534        (class->flush == NULL || class->close_async == g_output_stream_real_close_async)))
1535     {
1536       class->close_async (stream, io_priority, cancellable,
1537                           async_ready_close_callback_wrapper, task);
1538     }
1539   else
1540     {
1541       /* First do an async flush, then do the async close in the callback
1542          wrapper (see async_ready_close_flushed_callback_wrapper) */
1543       class->flush_async (stream, io_priority, cancellable,
1544                           async_ready_close_flushed_callback_wrapper, task);
1545     }
1546 }
1547
1548 static gboolean
1549 g_output_stream_internal_close_finish (GOutputStream  *stream,
1550                                        GAsyncResult   *result,
1551                                        GError        **error)
1552 {
1553   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1554   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1555   g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_internal_close_async), FALSE);
1556
1557   return g_task_propagate_boolean (G_TASK (result), error);
1558 }
1559
1560 /**
1561  * g_output_stream_close_finish:
1562  * @stream: a #GOutputStream.
1563  * @result: a #GAsyncResult.
1564  * @error: a #GError location to store the error occurring, or %NULL to 
1565  * ignore.
1566  * 
1567  * Closes an output stream.
1568  * 
1569  * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
1570  **/
1571 gboolean
1572 g_output_stream_close_finish (GOutputStream  *stream,
1573                               GAsyncResult   *result,
1574                               GError        **error)
1575 {
1576   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1577   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1578   g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_close_async), FALSE);
1579
1580   /* @result is always the GTask created by g_output_stream_close_async();
1581    * we called class->close_finish() from async_ready_close_callback_wrapper.
1582    */
1583   return g_task_propagate_boolean (G_TASK (result), error);
1584 }
1585
1586 /**
1587  * g_output_stream_is_closed:
1588  * @stream: a #GOutputStream.
1589  * 
1590  * Checks if an output stream has already been closed.
1591  * 
1592  * Returns: %TRUE if @stream is closed. %FALSE otherwise. 
1593  **/
1594 gboolean
1595 g_output_stream_is_closed (GOutputStream *stream)
1596 {
1597   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1598   
1599   return stream->priv->closed;
1600 }
1601
1602 /**
1603  * g_output_stream_is_closing:
1604  * @stream: a #GOutputStream.
1605  *
1606  * Checks if an output stream is being closed. This can be
1607  * used inside e.g. a flush implementation to see if the
1608  * flush (or other i/o operation) is called from within
1609  * the closing operation.
1610  *
1611  * Returns: %TRUE if @stream is being closed. %FALSE otherwise.
1612  *
1613  * Since: 2.24
1614  **/
1615 gboolean
1616 g_output_stream_is_closing (GOutputStream *stream)
1617 {
1618   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1619
1620   return stream->priv->closing;
1621 }
1622
1623 /**
1624  * g_output_stream_has_pending:
1625  * @stream: a #GOutputStream.
1626  * 
1627  * Checks if an output stream has pending actions.
1628  * 
1629  * Returns: %TRUE if @stream has pending actions. 
1630  **/
1631 gboolean
1632 g_output_stream_has_pending (GOutputStream *stream)
1633 {
1634   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1635   
1636   return stream->priv->pending;
1637 }
1638
1639 /**
1640  * g_output_stream_set_pending:
1641  * @stream: a #GOutputStream.
1642  * @error: a #GError location to store the error occurring, or %NULL to 
1643  * ignore.
1644  * 
1645  * Sets @stream to have actions pending. If the pending flag is
1646  * already set or @stream is closed, it will return %FALSE and set
1647  * @error.
1648  *
1649  * Returns: %TRUE if pending was previously unset and is now set.
1650  **/
1651 gboolean
1652 g_output_stream_set_pending (GOutputStream *stream,
1653                              GError **error)
1654 {
1655   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1656   
1657   if (stream->priv->closed)
1658     {
1659       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1660                            _("Stream is already closed"));
1661       return FALSE;
1662     }
1663   
1664   if (stream->priv->pending)
1665     {
1666       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
1667                            /* Translators: This is an error you get if there is
1668                             * already an operation running against this stream when
1669                             * you try to start one */
1670                            _("Stream has outstanding operation"));
1671       return FALSE;
1672     }
1673   
1674   stream->priv->pending = TRUE;
1675   return TRUE;
1676 }
1677
1678 /**
1679  * g_output_stream_clear_pending:
1680  * @stream: output stream
1681  * 
1682  * Clears the pending flag on @stream.
1683  **/
1684 void
1685 g_output_stream_clear_pending (GOutputStream *stream)
1686 {
1687   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1688   
1689   stream->priv->pending = FALSE;
1690 }
1691
1692 /*< internal >
1693  * g_output_stream_async_write_is_via_threads:
1694  * @stream: a #GOutputStream.
1695  *
1696  * Checks if an output stream's write_async function uses threads.
1697  *
1698  * Returns: %TRUE if @stream's write_async function uses threads.
1699  **/
1700 gboolean
1701 g_output_stream_async_write_is_via_threads (GOutputStream *stream)
1702 {
1703   GOutputStreamClass *class;
1704
1705   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1706
1707   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1708
1709   return (class->write_async == g_output_stream_real_write_async &&
1710       !(G_IS_POLLABLE_OUTPUT_STREAM (stream) &&
1711         g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (stream))));
1712 }
1713
1714 /*< internal >
1715  * g_output_stream_async_close_is_via_threads:
1716  * @stream: output stream
1717  *
1718  * Checks if an output stream's close_async function uses threads.
1719  *
1720  * Returns: %TRUE if @stream's close_async function uses threads.
1721  **/
1722 gboolean
1723 g_output_stream_async_close_is_via_threads (GOutputStream *stream)
1724 {
1725   GOutputStreamClass *class;
1726
1727   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1728
1729   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1730
1731   return class->close_async == g_output_stream_real_close_async;
1732 }
1733
1734 /********************************************
1735  *   Default implementation of async ops    *
1736  ********************************************/
1737
1738 typedef struct {
1739   const void         *buffer;
1740   gsize               count_requested;
1741   gssize              count_written;
1742 } WriteData;
1743
1744 static void
1745 free_write_data (WriteData *op)
1746 {
1747   g_slice_free (WriteData, op);
1748 }
1749
1750 static void
1751 write_async_thread (GTask        *task,
1752                     gpointer      source_object,
1753                     gpointer      task_data,
1754                     GCancellable *cancellable)
1755 {
1756   GOutputStream *stream = source_object;
1757   WriteData *op = task_data;
1758   GOutputStreamClass *class;
1759   GError *error = NULL;
1760   gssize count_written;
1761
1762   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1763   count_written = class->write_fn (stream, op->buffer, op->count_requested,
1764                                    cancellable, &error);
1765   if (count_written == -1)
1766     g_task_return_error (task, error);
1767   else
1768     g_task_return_int (task, count_written);
1769 }
1770
1771 static void write_async_pollable (GPollableOutputStream *stream,
1772                                   GTask                 *task);
1773
1774 static gboolean
1775 write_async_pollable_ready (GPollableOutputStream *stream,
1776                             gpointer               user_data)
1777 {
1778   GTask *task = user_data;
1779
1780   write_async_pollable (stream, task);
1781   return FALSE;
1782 }
1783
1784 static void
1785 write_async_pollable (GPollableOutputStream *stream,
1786                       GTask                 *task)
1787 {
1788   GError *error = NULL;
1789   WriteData *op = g_task_get_task_data (task);
1790   gssize count_written;
1791
1792   if (g_task_return_error_if_cancelled (task))
1793     return;
1794
1795   count_written = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->
1796     write_nonblocking (stream, op->buffer, op->count_requested, &error);
1797
1798   if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
1799     {
1800       GSource *source;
1801
1802       g_error_free (error);
1803
1804       source = g_pollable_output_stream_create_source (stream,
1805                                                        g_task_get_cancellable (task));
1806       g_task_attach_source (task, source,
1807                             (GSourceFunc) write_async_pollable_ready);
1808       g_source_unref (source);
1809       return;
1810     }
1811
1812   if (count_written == -1)
1813     g_task_return_error (task, error);
1814   else
1815     g_task_return_int (task, count_written);
1816 }
1817
1818 static void
1819 g_output_stream_real_write_async (GOutputStream       *stream,
1820                                   const void          *buffer,
1821                                   gsize                count,
1822                                   int                  io_priority,
1823                                   GCancellable        *cancellable,
1824                                   GAsyncReadyCallback  callback,
1825                                   gpointer             user_data)
1826 {
1827   GTask *task;
1828   WriteData *op;
1829
1830   op = g_slice_new0 (WriteData);
1831   task = g_task_new (stream, cancellable, callback, user_data);
1832   g_task_set_check_cancellable (task, FALSE);
1833   g_task_set_task_data (task, op, (GDestroyNotify) free_write_data);
1834   op->buffer = buffer;
1835   op->count_requested = count;
1836
1837   if (!g_output_stream_async_write_is_via_threads (stream))
1838     write_async_pollable (G_POLLABLE_OUTPUT_STREAM (stream), task);
1839   else
1840     g_task_run_in_thread (task, write_async_thread);
1841   g_object_unref (task);
1842 }
1843
1844 static gssize
1845 g_output_stream_real_write_finish (GOutputStream  *stream,
1846                                    GAsyncResult   *result,
1847                                    GError        **error)
1848 {
1849   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1850
1851   return g_task_propagate_int (G_TASK (result), error);
1852 }
1853
1854 typedef struct {
1855   GInputStream *source;
1856   GOutputStreamSpliceFlags flags;
1857   gssize n_read;
1858   gssize n_written;
1859   gsize bytes_copied;
1860   GError *error;
1861   guint8 *buffer;
1862 } SpliceData;
1863
1864 static void
1865 free_splice_data (SpliceData *op)
1866 {
1867   g_clear_pointer (&op->buffer, g_free);
1868   g_object_unref (op->source);
1869   g_clear_error (&op->error);
1870   g_free (op);
1871 }
1872
1873 static void
1874 real_splice_async_complete_cb (GTask *task)
1875 {
1876   SpliceData *op = g_task_get_task_data (task);
1877
1878   if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE &&
1879       !g_input_stream_is_closed (op->source))
1880     return;
1881
1882   if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET &&
1883       !g_output_stream_is_closed (g_task_get_source_object (task)))
1884     return;
1885
1886   if (op->error != NULL)
1887     {
1888       g_task_return_error (task, op->error);
1889       op->error = NULL;
1890     }
1891   else
1892     {
1893       g_task_return_int (task, op->bytes_copied);
1894     }
1895
1896   g_object_unref (task);
1897 }
1898
1899 static void
1900 real_splice_async_close_input_cb (GObject      *source,
1901                                   GAsyncResult *res,
1902                                   gpointer      user_data)
1903 {
1904   GTask *task = user_data;
1905
1906   g_input_stream_close_finish (G_INPUT_STREAM (source), res, NULL);
1907
1908   real_splice_async_complete_cb (task);
1909 }
1910
1911 static void
1912 real_splice_async_close_output_cb (GObject      *source,
1913                                    GAsyncResult *res,
1914                                    gpointer      user_data)
1915 {
1916   GTask *task = G_TASK (user_data);
1917   SpliceData *op = g_task_get_task_data (task);
1918   GError **error = (op->error == NULL) ? &op->error : NULL;
1919
1920   g_output_stream_internal_close_finish (G_OUTPUT_STREAM (source), res, error);
1921
1922   real_splice_async_complete_cb (task);
1923 }
1924
1925 static void
1926 real_splice_async_complete (GTask *task)
1927 {
1928   SpliceData *op = g_task_get_task_data (task);
1929   gboolean done = TRUE;
1930
1931   if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
1932     {
1933       done = FALSE;
1934       g_input_stream_close_async (op->source, g_task_get_priority (task),
1935                                   g_task_get_cancellable (task),
1936                                   real_splice_async_close_input_cb, task);
1937     }
1938
1939   if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
1940     {
1941       done = FALSE;
1942       g_output_stream_internal_close_async (g_task_get_source_object (task),
1943                                             g_task_get_priority (task),
1944                                             g_task_get_cancellable (task),
1945                                             real_splice_async_close_output_cb,
1946                                             task);
1947     }
1948
1949   if (done)
1950     real_splice_async_complete_cb (task);
1951 }
1952
1953 static void real_splice_async_read_cb (GObject      *source,
1954                                        GAsyncResult *res,
1955                                        gpointer      user_data);
1956
1957 static void
1958 real_splice_async_write_cb (GObject      *source,
1959                             GAsyncResult *res,
1960                             gpointer      user_data)
1961 {
1962   GOutputStreamClass *class;
1963   GTask *task = G_TASK (user_data);
1964   SpliceData *op = g_task_get_task_data (task);
1965   gssize ret;
1966
1967   class = G_OUTPUT_STREAM_GET_CLASS (g_task_get_source_object (task));
1968
1969   ret = class->write_finish (G_OUTPUT_STREAM (source), res, &op->error);
1970
1971   if (ret == -1)
1972     {
1973       real_splice_async_complete (task);
1974       return;
1975     }
1976
1977   op->n_written += ret;
1978   op->bytes_copied += ret;
1979   if (op->bytes_copied > G_MAXSSIZE)
1980     op->bytes_copied = G_MAXSSIZE;
1981
1982   if (op->n_written < op->n_read)
1983     {
1984       class->write_async (g_task_get_source_object (task),
1985                           op->buffer + op->n_written,
1986                           op->n_read - op->n_written,
1987                           g_task_get_priority (task),
1988                           g_task_get_cancellable (task),
1989                           real_splice_async_write_cb, task);
1990       return;
1991     }
1992
1993   g_input_stream_read_async (op->source, op->buffer, 8192,
1994                              g_task_get_priority (task),
1995                              g_task_get_cancellable (task),
1996                              real_splice_async_read_cb, task);
1997 }
1998
1999 static void
2000 real_splice_async_read_cb (GObject      *source,
2001                            GAsyncResult *res,
2002                            gpointer      user_data)
2003 {
2004   GOutputStreamClass *class;
2005   GTask *task = G_TASK (user_data);
2006   SpliceData *op = g_task_get_task_data (task);
2007   gssize ret;
2008
2009   class = G_OUTPUT_STREAM_GET_CLASS (g_task_get_source_object (task));
2010
2011   ret = g_input_stream_read_finish (op->source, res, &op->error);
2012   if (ret == -1 || ret == 0)
2013     {
2014       real_splice_async_complete (task);
2015       return;
2016     }
2017
2018   op->n_read = ret;
2019   op->n_written = 0;
2020
2021   class->write_async (g_task_get_source_object (task), op->buffer,
2022                       op->n_read, g_task_get_priority (task),
2023                       g_task_get_cancellable (task),
2024                       real_splice_async_write_cb, task);
2025 }
2026
2027 static void
2028 splice_async_thread (GTask        *task,
2029                      gpointer      source_object,
2030                      gpointer      task_data,
2031                      GCancellable *cancellable)
2032 {
2033   GOutputStream *stream = source_object;
2034   SpliceData *op = task_data;
2035   GOutputStreamClass *class;
2036   GError *error = NULL;
2037   gssize bytes_copied;
2038
2039   class = G_OUTPUT_STREAM_GET_CLASS (stream);
2040   
2041   bytes_copied = class->splice (stream,
2042                                 op->source,
2043                                 op->flags,
2044                                 cancellable,
2045                                 &error);
2046   if (bytes_copied == -1)
2047     g_task_return_error (task, error);
2048   else
2049     g_task_return_int (task, bytes_copied);
2050 }
2051
2052 static void
2053 g_output_stream_real_splice_async (GOutputStream             *stream,
2054                                    GInputStream              *source,
2055                                    GOutputStreamSpliceFlags   flags,
2056                                    int                        io_priority,
2057                                    GCancellable              *cancellable,
2058                                    GAsyncReadyCallback        callback,
2059                                    gpointer                   user_data)
2060 {
2061   GTask *task;
2062   SpliceData *op;
2063
2064   op = g_new0 (SpliceData, 1);
2065   task = g_task_new (stream, cancellable, callback, user_data);
2066   g_task_set_task_data (task, op, (GDestroyNotify)free_splice_data);
2067   op->flags = flags;
2068   op->source = g_object_ref (source);
2069
2070   if (g_input_stream_async_read_is_via_threads (source) &&
2071       g_output_stream_async_write_is_via_threads (stream))
2072     {
2073       g_task_run_in_thread (task, splice_async_thread);
2074       g_object_unref (task);
2075     }
2076   else
2077     {
2078       op->buffer = g_malloc (8192);
2079       g_input_stream_read_async (op->source, op->buffer, 8192,
2080                                  g_task_get_priority (task),
2081                                  g_task_get_cancellable (task),
2082                                  real_splice_async_read_cb, task);
2083     }
2084 }
2085
2086 static gssize
2087 g_output_stream_real_splice_finish (GOutputStream  *stream,
2088                                     GAsyncResult   *result,
2089                                     GError        **error)
2090 {
2091   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
2092
2093   return g_task_propagate_int (G_TASK (result), error);
2094 }
2095
2096
2097 static void
2098 flush_async_thread (GTask        *task,
2099                     gpointer      source_object,
2100                     gpointer      task_data,
2101                     GCancellable *cancellable)
2102 {
2103   GOutputStream *stream = source_object;
2104   GOutputStreamClass *class;
2105   gboolean result;
2106   GError *error = NULL;
2107
2108   class = G_OUTPUT_STREAM_GET_CLASS (stream);
2109   result = TRUE;
2110   if (class->flush)
2111     result = class->flush (stream, cancellable, &error);
2112
2113   if (result)
2114     g_task_return_boolean (task, TRUE);
2115   else
2116     g_task_return_error (task, error);
2117 }
2118
2119 static void
2120 g_output_stream_real_flush_async (GOutputStream       *stream,
2121                                   int                  io_priority,
2122                                   GCancellable        *cancellable,
2123                                   GAsyncReadyCallback  callback,
2124                                   gpointer             user_data)
2125 {
2126   GTask *task;
2127
2128   task = g_task_new (stream, cancellable, callback, user_data);
2129   g_task_set_priority (task, io_priority);
2130   g_task_run_in_thread (task, flush_async_thread);
2131   g_object_unref (task);
2132 }
2133
2134 static gboolean
2135 g_output_stream_real_flush_finish (GOutputStream  *stream,
2136                                    GAsyncResult   *result,
2137                                    GError        **error)
2138 {
2139   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
2140
2141   return g_task_propagate_boolean (G_TASK (result), error);
2142 }
2143
2144 static void
2145 close_async_thread (GTask        *task,
2146                     gpointer      source_object,
2147                     gpointer      task_data,
2148                     GCancellable *cancellable)
2149 {
2150   GOutputStream *stream = source_object;
2151   GOutputStreamClass *class;
2152   GError *error = NULL;
2153   gboolean result = TRUE;
2154
2155   class = G_OUTPUT_STREAM_GET_CLASS (stream);
2156
2157   /* Do a flush here if there is a flush function, and we did not have to do
2158    * an async flush before (see g_output_stream_close_async)
2159    */
2160   if (class->flush != NULL &&
2161       (class->flush_async == NULL ||
2162        class->flush_async == g_output_stream_real_flush_async))
2163     {
2164       result = class->flush (stream, cancellable, &error);
2165     }
2166
2167   /* Auto handling of cancelation disabled, and ignore
2168      cancellation, since we want to close things anyway, although
2169      possibly in a quick-n-dirty way. At least we never want to leak
2170      open handles */
2171
2172   if (class->close_fn)
2173     {
2174       /* Make sure to close, even if the flush failed (see sync close) */
2175       if (!result)
2176         class->close_fn (stream, cancellable, NULL);
2177       else
2178         result = class->close_fn (stream, cancellable, &error);
2179     }
2180
2181   if (result)
2182     g_task_return_boolean (task, TRUE);
2183   else
2184     g_task_return_error (task, error);
2185 }
2186
2187 static void
2188 g_output_stream_real_close_async (GOutputStream       *stream,
2189                                   int                  io_priority,
2190                                   GCancellable        *cancellable,
2191                                   GAsyncReadyCallback  callback,
2192                                   gpointer             user_data)
2193 {
2194   GTask *task;
2195
2196   task = g_task_new (stream, cancellable, callback, user_data);
2197   g_task_set_priority (task, io_priority);
2198   g_task_run_in_thread (task, close_async_thread);
2199   g_object_unref (task);
2200 }
2201
2202 static gboolean
2203 g_output_stream_real_close_finish (GOutputStream  *stream,
2204                                    GAsyncResult   *result,
2205                                    GError        **error)
2206 {
2207   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
2208
2209   return g_task_propagate_boolean (G_TASK (result), error);
2210 }