nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 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: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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 asyncronous 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: (allow-none): 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_task_data (task, data, free_async_write_all);
1002 g_task_set_priority (task, io_priority);
1003  
1004 /* If async writes are going to be handled via the threadpool anyway
1005 * then we may as well do it with a single dispatch instead of
1006 * bouncing in and out.
1007 */
1008 if (g_output_stream_async_write_is_via_threads (stream))
1009 {
1010 g_task_run_in_thread (task, write_all_async_thread);
1011 g_object_unref (task);
1012 }
1013 else
1014 write_all_callback (G_OBJECT (stream), NULL, task);
1015 }
1016  
1017 /**
1018 * g_output_stream_write_all_finish:
1019 * @stream: a #GOutputStream
1020 * @result: a #GAsyncResult
1021 * @bytes_written: (out): location to store the number of bytes that was written to the stream
1022 * @error: a #GError location to store the error occurring, or %NULL to ignore.
1023 *
1024 * Finishes an asynchronous stream write operation started with
1025 * g_output_stream_write_all_async().
1026 *
1027 * As a special exception to the normal conventions for functions that
1028 * use #GError, if this function returns %FALSE (and sets @error) then
1029 * @bytes_written will be set to the number of bytes that were
1030 * successfully written before the error was encountered. This
1031 * functionality is only available from C. If you need it from another
1032 * language then you must write your own loop around
1033 * g_output_stream_write_async().
1034 *
1035 * Returns: %TRUE on success, %FALSE if there was an error
1036 *
1037 * Since: 2.44
1038 **/
1039 gboolean
1040 g_output_stream_write_all_finish (GOutputStream *stream,
1041 GAsyncResult *result,
1042 gsize *bytes_written,
1043 GError **error)
1044 {
1045 GTask *task;
1046  
1047 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1048 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1049  
1050 task = G_TASK (result);
1051  
1052 if (bytes_written)
1053 {
1054 AsyncWriteAll *data = (AsyncWriteAll *)g_task_get_task_data (task);
1055  
1056 *bytes_written = data->bytes_written;
1057 }
1058  
1059 return g_task_propagate_boolean (task, error);
1060 }
1061  
1062 static void
1063 write_bytes_callback (GObject *stream,
1064 GAsyncResult *result,
1065 gpointer user_data)
1066 {
1067 GTask *task = user_data;
1068 GError *error = NULL;
1069 gssize nwrote;
1070  
1071 nwrote = g_output_stream_write_finish (G_OUTPUT_STREAM (stream),
1072 result, &error);
1073 if (nwrote == -1)
1074 g_task_return_error (task, error);
1075 else
1076 g_task_return_int (task, nwrote);
1077 g_object_unref (task);
1078 }
1079  
1080 /**
1081 * g_output_stream_write_bytes_async:
1082 * @stream: A #GOutputStream.
1083 * @bytes: The bytes to write
1084 * @io_priority: the io priority of the request.
1085 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
1086 * @callback: (scope async): callback to call when the request is satisfied
1087 * @user_data: (closure): the data to pass to callback function
1088 *
1089 * This function is similar to g_output_stream_write_async(), but
1090 * takes a #GBytes as input. Due to the refcounted nature of #GBytes,
1091 * this allows the stream to avoid taking a copy of the data.
1092 *
1093 * However, note that this function may still perform partial writes,
1094 * just like g_output_stream_write_async(). If that occurs, to continue
1095 * writing, you will need to create a new #GBytes containing just the
1096 * remaining bytes, using g_bytes_new_from_bytes(). Passing the same
1097 * #GBytes instance multiple times potentially can result in duplicated
1098 * data in the output stream.
1099 *
1100 * For the synchronous, blocking version of this function, see
1101 * g_output_stream_write_bytes().
1102 **/
1103 void
1104 g_output_stream_write_bytes_async (GOutputStream *stream,
1105 GBytes *bytes,
1106 int io_priority,
1107 GCancellable *cancellable,
1108 GAsyncReadyCallback callback,
1109 gpointer user_data)
1110 {
1111 GTask *task;
1112 gsize size;
1113 gconstpointer data;
1114  
1115 data = g_bytes_get_data (bytes, &size);
1116  
1117 task = g_task_new (stream, cancellable, callback, user_data);
1118 g_task_set_task_data (task, g_bytes_ref (bytes),
1119 (GDestroyNotify) g_bytes_unref);
1120  
1121 g_output_stream_write_async (stream,
1122 data, size,
1123 io_priority,
1124 cancellable,
1125 write_bytes_callback,
1126 task);
1127 }
1128  
1129 /**
1130 * g_output_stream_write_bytes_finish:
1131 * @stream: a #GOutputStream.
1132 * @result: a #GAsyncResult.
1133 * @error: a #GError location to store the error occurring, or %NULL to
1134 * ignore.
1135 *
1136 * Finishes a stream write-from-#GBytes operation.
1137 *
1138 * Returns: a #gssize containing the number of bytes written to the stream.
1139 **/
1140 gssize
1141 g_output_stream_write_bytes_finish (GOutputStream *stream,
1142 GAsyncResult *result,
1143 GError **error)
1144 {
1145 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
1146 g_return_val_if_fail (g_task_is_valid (result, stream), -1);
1147  
1148 return g_task_propagate_int (G_TASK (result), error);
1149 }
1150  
1151 static void
1152 async_ready_splice_callback_wrapper (GObject *source_object,
1153 GAsyncResult *res,
1154 gpointer _data)
1155 {
1156 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1157 GOutputStreamClass *class;
1158 GTask *task = _data;
1159 gssize nspliced;
1160 GError *error = NULL;
1161  
1162 g_output_stream_clear_pending (stream);
1163  
1164 if (g_async_result_legacy_propagate_error (res, &error))
1165 nspliced = -1;
1166 else
1167 {
1168 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1169 nspliced = class->splice_finish (stream, res, &error);
1170 }
1171  
1172 if (nspliced >= 0)
1173 g_task_return_int (task, nspliced);
1174 else
1175 g_task_return_error (task, error);
1176 g_object_unref (task);
1177 }
1178  
1179 /**
1180 * g_output_stream_splice_async:
1181 * @stream: a #GOutputStream.
1182 * @source: a #GInputStream.
1183 * @flags: a set of #GOutputStreamSpliceFlags.
1184 * @io_priority: the io priority of the request.
1185 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
1186 * @callback: (scope async): a #GAsyncReadyCallback.
1187 * @user_data: (closure): user data passed to @callback.
1188 *
1189 * Splices a stream asynchronously.
1190 * When the operation is finished @callback will be called.
1191 * You can then call g_output_stream_splice_finish() to get the
1192 * result of the operation.
1193 *
1194 * For the synchronous, blocking version of this function, see
1195 * g_output_stream_splice().
1196 **/
1197 void
1198 g_output_stream_splice_async (GOutputStream *stream,
1199 GInputStream *source,
1200 GOutputStreamSpliceFlags flags,
1201 int io_priority,
1202 GCancellable *cancellable,
1203 GAsyncReadyCallback callback,
1204 gpointer user_data)
1205 {
1206 GOutputStreamClass *class;
1207 GTask *task;
1208 GError *error = NULL;
1209  
1210 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1211 g_return_if_fail (G_IS_INPUT_STREAM (source));
1212  
1213 task = g_task_new (stream, cancellable, callback, user_data);
1214 g_task_set_source_tag (task, g_output_stream_splice_async);
1215 g_task_set_priority (task, io_priority);
1216 g_task_set_task_data (task, g_object_ref (source), g_object_unref);
1217  
1218 if (g_input_stream_is_closed (source))
1219 {
1220 g_task_return_new_error (task,
1221 G_IO_ERROR, G_IO_ERROR_CLOSED,
1222 _("Source stream is already closed"));
1223 g_object_unref (task);
1224 return;
1225 }
1226  
1227 if (!g_output_stream_set_pending (stream, &error))
1228 {
1229 g_task_return_error (task, error);
1230 g_object_unref (task);
1231 return;
1232 }
1233  
1234 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1235  
1236 class->splice_async (stream, source, flags, io_priority, cancellable,
1237 async_ready_splice_callback_wrapper, task);
1238 }
1239  
1240 /**
1241 * g_output_stream_splice_finish:
1242 * @stream: a #GOutputStream.
1243 * @result: a #GAsyncResult.
1244 * @error: a #GError location to store the error occurring, or %NULL to
1245 * ignore.
1246 *
1247 * Finishes an asynchronous stream splice operation.
1248 *
1249 * Returns: a #gssize of the number of bytes spliced. Note that if the
1250 * number of bytes spliced is greater than %G_MAXSSIZE, then that
1251 * will be returned, and there is no way to determine the actual
1252 * number of bytes spliced.
1253 **/
1254 gssize
1255 g_output_stream_splice_finish (GOutputStream *stream,
1256 GAsyncResult *result,
1257 GError **error)
1258 {
1259 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1260 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1261 g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_splice_async), FALSE);
1262  
1263 /* @result is always the GTask created by g_output_stream_splice_async();
1264 * we called class->splice_finish() from async_ready_splice_callback_wrapper.
1265 */
1266 return g_task_propagate_int (G_TASK (result), error);
1267 }
1268  
1269 static void
1270 async_ready_flush_callback_wrapper (GObject *source_object,
1271 GAsyncResult *res,
1272 gpointer user_data)
1273 {
1274 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1275 GOutputStreamClass *class;
1276 GTask *task = user_data;
1277 gboolean flushed;
1278 GError *error = NULL;
1279  
1280 g_output_stream_clear_pending (stream);
1281  
1282 if (g_async_result_legacy_propagate_error (res, &error))
1283 flushed = FALSE;
1284 else
1285 {
1286 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1287 flushed = class->flush_finish (stream, res, &error);
1288 }
1289  
1290 if (flushed)
1291 g_task_return_boolean (task, TRUE);
1292 else
1293 g_task_return_error (task, error);
1294 g_object_unref (task);
1295 }
1296  
1297 /**
1298 * g_output_stream_flush_async:
1299 * @stream: a #GOutputStream.
1300 * @io_priority: the io priority of the request.
1301 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
1302 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
1303 * @user_data: (closure): the data to pass to callback function
1304 *
1305 * Forces an asynchronous write of all user-space buffered data for
1306 * the given @stream.
1307 * For behaviour details see g_output_stream_flush().
1308 *
1309 * When the operation is finished @callback will be
1310 * called. You can then call g_output_stream_flush_finish() to get the
1311 * result of the operation.
1312 **/
1313 void
1314 g_output_stream_flush_async (GOutputStream *stream,
1315 int io_priority,
1316 GCancellable *cancellable,
1317 GAsyncReadyCallback callback,
1318 gpointer user_data)
1319 {
1320 GOutputStreamClass *class;
1321 GTask *task;
1322 GError *error = NULL;
1323  
1324 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1325  
1326 task = g_task_new (stream, cancellable, callback, user_data);
1327 g_task_set_source_tag (task, g_output_stream_flush_async);
1328 g_task_set_priority (task, io_priority);
1329  
1330 if (!g_output_stream_set_pending (stream, &error))
1331 {
1332 g_task_return_error (task, error);
1333 g_object_unref (task);
1334 return;
1335 }
1336  
1337 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1338  
1339 if (class->flush_async == NULL)
1340 {
1341 g_task_return_boolean (task, TRUE);
1342 g_object_unref (task);
1343 return;
1344 }
1345  
1346 class->flush_async (stream, io_priority, cancellable,
1347 async_ready_flush_callback_wrapper, task);
1348 }
1349  
1350 /**
1351 * g_output_stream_flush_finish:
1352 * @stream: a #GOutputStream.
1353 * @result: a GAsyncResult.
1354 * @error: a #GError location to store the error occurring, or %NULL to
1355 * ignore.
1356 *
1357 * Finishes flushing an output stream.
1358 *
1359 * Returns: %TRUE if flush operation succeeded, %FALSE otherwise.
1360 **/
1361 gboolean
1362 g_output_stream_flush_finish (GOutputStream *stream,
1363 GAsyncResult *result,
1364 GError **error)
1365 {
1366 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1367 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1368 g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_flush_async), FALSE);
1369  
1370 /* @result is always the GTask created by g_output_stream_flush_async();
1371 * we called class->flush_finish() from async_ready_flush_callback_wrapper.
1372 */
1373 return g_task_propagate_boolean (G_TASK (result), error);
1374 }
1375  
1376  
1377 static void
1378 async_ready_close_callback_wrapper (GObject *source_object,
1379 GAsyncResult *res,
1380 gpointer user_data)
1381 {
1382 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1383 GOutputStreamClass *class;
1384 GTask *task = user_data;
1385 GError *error = g_task_get_task_data (task);
1386  
1387 stream->priv->closing = FALSE;
1388 stream->priv->closed = TRUE;
1389  
1390 if (!error && !g_async_result_legacy_propagate_error (res, &error))
1391 {
1392 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1393  
1394 class->close_finish (stream, res,
1395 error ? NULL : &error);
1396 }
1397  
1398 if (error != NULL)
1399 g_task_return_error (task, error);
1400 else
1401 g_task_return_boolean (task, TRUE);
1402 g_object_unref (task);
1403 }
1404  
1405 static void
1406 async_ready_close_flushed_callback_wrapper (GObject *source_object,
1407 GAsyncResult *res,
1408 gpointer user_data)
1409 {
1410 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1411 GOutputStreamClass *class;
1412 GTask *task = user_data;
1413 GError *error = NULL;
1414  
1415 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1416  
1417 if (!g_async_result_legacy_propagate_error (res, &error))
1418 {
1419 class->flush_finish (stream, res, &error);
1420 }
1421  
1422 /* propagate the possible error */
1423 if (error)
1424 g_task_set_task_data (task, error, NULL);
1425  
1426 /* we still close, even if there was a flush error */
1427 class->close_async (stream,
1428 g_task_get_priority (task),
1429 g_task_get_cancellable (task),
1430 async_ready_close_callback_wrapper, task);
1431 }
1432  
1433 static void
1434 real_close_async_cb (GObject *source_object,
1435 GAsyncResult *res,
1436 gpointer user_data)
1437 {
1438 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
1439 GTask *task = user_data;
1440 GError *error = NULL;
1441 gboolean ret;
1442  
1443 g_output_stream_clear_pending (stream);
1444  
1445 ret = g_output_stream_internal_close_finish (stream, res, &error);
1446  
1447 if (error != NULL)
1448 g_task_return_error (task, error);
1449 else
1450 g_task_return_boolean (task, ret);
1451  
1452 g_object_unref (task);
1453 }
1454  
1455 /**
1456 * g_output_stream_close_async:
1457 * @stream: A #GOutputStream.
1458 * @io_priority: the io priority of the request.
1459 * @cancellable: (allow-none): optional cancellable object
1460 * @callback: (scope async): callback to call when the request is satisfied
1461 * @user_data: (closure): the data to pass to callback function
1462 *
1463 * Requests an asynchronous close of the stream, releasing resources
1464 * related to it. When the operation is finished @callback will be
1465 * called. You can then call g_output_stream_close_finish() to get
1466 * the result of the operation.
1467 *
1468 * For behaviour details see g_output_stream_close().
1469 *
1470 * The asyncronous methods have a default fallback that uses threads
1471 * to implement asynchronicity, so they are optional for inheriting
1472 * classes. However, if you override one you must override all.
1473 **/
1474 void
1475 g_output_stream_close_async (GOutputStream *stream,
1476 int io_priority,
1477 GCancellable *cancellable,
1478 GAsyncReadyCallback callback,
1479 gpointer user_data)
1480 {
1481 GTask *task;
1482 GError *error = NULL;
1483  
1484 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1485  
1486 task = g_task_new (stream, cancellable, callback, user_data);
1487 g_task_set_source_tag (task, g_output_stream_close_async);
1488 g_task_set_priority (task, io_priority);
1489  
1490 if (!g_output_stream_set_pending (stream, &error))
1491 {
1492 g_task_return_error (task, error);
1493 g_object_unref (task);
1494 return;
1495 }
1496  
1497 g_output_stream_internal_close_async (stream, io_priority, cancellable,
1498 real_close_async_cb, task);
1499 }
1500  
1501 /* Must always be called inside
1502 * g_output_stream_set_pending()/g_output_stream_clear_pending().
1503 */
1504 void
1505 g_output_stream_internal_close_async (GOutputStream *stream,
1506 int io_priority,
1507 GCancellable *cancellable,
1508 GAsyncReadyCallback callback,
1509 gpointer user_data)
1510 {
1511 GOutputStreamClass *class;
1512 GTask *task;
1513  
1514 task = g_task_new (stream, cancellable, callback, user_data);
1515 g_task_set_source_tag (task, g_output_stream_internal_close_async);
1516 g_task_set_priority (task, io_priority);
1517  
1518 if (stream->priv->closed)
1519 {
1520 g_task_return_boolean (task, TRUE);
1521 g_object_unref (task);
1522 return;
1523 }
1524  
1525 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1526 stream->priv->closing = TRUE;
1527  
1528 /* Call close_async directly if there is no need to flush, or if the flush
1529 can be done sync (in the output stream async close thread) */
1530 if (class->flush_async == NULL ||
1531 (class->flush_async == g_output_stream_real_flush_async &&
1532 (class->flush == NULL || class->close_async == g_output_stream_real_close_async)))
1533 {
1534 class->close_async (stream, io_priority, cancellable,
1535 async_ready_close_callback_wrapper, task);
1536 }
1537 else
1538 {
1539 /* First do an async flush, then do the async close in the callback
1540 wrapper (see async_ready_close_flushed_callback_wrapper) */
1541 class->flush_async (stream, io_priority, cancellable,
1542 async_ready_close_flushed_callback_wrapper, task);
1543 }
1544 }
1545  
1546 static gboolean
1547 g_output_stream_internal_close_finish (GOutputStream *stream,
1548 GAsyncResult *result,
1549 GError **error)
1550 {
1551 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1552 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1553 g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_internal_close_async), FALSE);
1554  
1555 return g_task_propagate_boolean (G_TASK (result), error);
1556 }
1557  
1558 /**
1559 * g_output_stream_close_finish:
1560 * @stream: a #GOutputStream.
1561 * @result: a #GAsyncResult.
1562 * @error: a #GError location to store the error occurring, or %NULL to
1563 * ignore.
1564 *
1565 * Closes an output stream.
1566 *
1567 * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
1568 **/
1569 gboolean
1570 g_output_stream_close_finish (GOutputStream *stream,
1571 GAsyncResult *result,
1572 GError **error)
1573 {
1574 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1575 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1576 g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_close_async), FALSE);
1577  
1578 /* @result is always the GTask created by g_output_stream_close_async();
1579 * we called class->close_finish() from async_ready_close_callback_wrapper.
1580 */
1581 return g_task_propagate_boolean (G_TASK (result), error);
1582 }
1583  
1584 /**
1585 * g_output_stream_is_closed:
1586 * @stream: a #GOutputStream.
1587 *
1588 * Checks if an output stream has already been closed.
1589 *
1590 * Returns: %TRUE if @stream is closed. %FALSE otherwise.
1591 **/
1592 gboolean
1593 g_output_stream_is_closed (GOutputStream *stream)
1594 {
1595 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1596  
1597 return stream->priv->closed;
1598 }
1599  
1600 /**
1601 * g_output_stream_is_closing:
1602 * @stream: a #GOutputStream.
1603 *
1604 * Checks if an output stream is being closed. This can be
1605 * used inside e.g. a flush implementation to see if the
1606 * flush (or other i/o operation) is called from within
1607 * the closing operation.
1608 *
1609 * Returns: %TRUE if @stream is being closed. %FALSE otherwise.
1610 *
1611 * Since: 2.24
1612 **/
1613 gboolean
1614 g_output_stream_is_closing (GOutputStream *stream)
1615 {
1616 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1617  
1618 return stream->priv->closing;
1619 }
1620  
1621 /**
1622 * g_output_stream_has_pending:
1623 * @stream: a #GOutputStream.
1624 *
1625 * Checks if an ouput stream has pending actions.
1626 *
1627 * Returns: %TRUE if @stream has pending actions.
1628 **/
1629 gboolean
1630 g_output_stream_has_pending (GOutputStream *stream)
1631 {
1632 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1633  
1634 return stream->priv->pending;
1635 }
1636  
1637 /**
1638 * g_output_stream_set_pending:
1639 * @stream: a #GOutputStream.
1640 * @error: a #GError location to store the error occurring, or %NULL to
1641 * ignore.
1642 *
1643 * Sets @stream to have actions pending. If the pending flag is
1644 * already set or @stream is closed, it will return %FALSE and set
1645 * @error.
1646 *
1647 * Returns: %TRUE if pending was previously unset and is now set.
1648 **/
1649 gboolean
1650 g_output_stream_set_pending (GOutputStream *stream,
1651 GError **error)
1652 {
1653 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1654  
1655 if (stream->priv->closed)
1656 {
1657 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1658 _("Stream is already closed"));
1659 return FALSE;
1660 }
1661  
1662 if (stream->priv->pending)
1663 {
1664 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
1665 /* Translators: This is an error you get if there is
1666 * already an operation running against this stream when
1667 * you try to start one */
1668 _("Stream has outstanding operation"));
1669 return FALSE;
1670 }
1671  
1672 stream->priv->pending = TRUE;
1673 return TRUE;
1674 }
1675  
1676 /**
1677 * g_output_stream_clear_pending:
1678 * @stream: output stream
1679 *
1680 * Clears the pending flag on @stream.
1681 **/
1682 void
1683 g_output_stream_clear_pending (GOutputStream *stream)
1684 {
1685 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1686  
1687 stream->priv->pending = FALSE;
1688 }
1689  
1690 /*< internal >
1691 * g_output_stream_async_write_is_via_threads:
1692 * @stream: a #GOutputStream.
1693 *
1694 * Checks if an ouput stream's write_async function uses threads.
1695 *
1696 * Returns: %TRUE if @stream's write_async function uses threads.
1697 **/
1698 gboolean
1699 g_output_stream_async_write_is_via_threads (GOutputStream *stream)
1700 {
1701 GOutputStreamClass *class;
1702  
1703 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1704  
1705 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1706  
1707 return (class->write_async == g_output_stream_real_write_async &&
1708 !(G_IS_POLLABLE_OUTPUT_STREAM (stream) &&
1709 g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (stream))));
1710 }
1711  
1712 /*< internal >
1713 * g_output_stream_async_close_is_via_threads:
1714 * @stream: output stream
1715 *
1716 * Checks if an output stream's close_async function uses threads.
1717 *
1718 * Returns: %TRUE if @stream's close_async function uses threads.
1719 **/
1720 gboolean
1721 g_output_stream_async_close_is_via_threads (GOutputStream *stream)
1722 {
1723 GOutputStreamClass *class;
1724  
1725 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1726  
1727 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1728  
1729 return class->close_async == g_output_stream_real_close_async;
1730 }
1731  
1732 /********************************************
1733 * Default implementation of async ops *
1734 ********************************************/
1735  
1736 typedef struct {
1737 const void *buffer;
1738 gsize count_requested;
1739 gssize count_written;
1740 } WriteData;
1741  
1742 static void
1743 free_write_data (WriteData *op)
1744 {
1745 g_slice_free (WriteData, op);
1746 }
1747  
1748 static void
1749 write_async_thread (GTask *task,
1750 gpointer source_object,
1751 gpointer task_data,
1752 GCancellable *cancellable)
1753 {
1754 GOutputStream *stream = source_object;
1755 WriteData *op = task_data;
1756 GOutputStreamClass *class;
1757 GError *error = NULL;
1758 gssize count_written;
1759  
1760 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1761 count_written = class->write_fn (stream, op->buffer, op->count_requested,
1762 cancellable, &error);
1763 if (count_written == -1)
1764 g_task_return_error (task, error);
1765 else
1766 g_task_return_int (task, count_written);
1767 }
1768  
1769 static void write_async_pollable (GPollableOutputStream *stream,
1770 GTask *task);
1771  
1772 static gboolean
1773 write_async_pollable_ready (GPollableOutputStream *stream,
1774 gpointer user_data)
1775 {
1776 GTask *task = user_data;
1777  
1778 write_async_pollable (stream, task);
1779 return FALSE;
1780 }
1781  
1782 static void
1783 write_async_pollable (GPollableOutputStream *stream,
1784 GTask *task)
1785 {
1786 GError *error = NULL;
1787 WriteData *op = g_task_get_task_data (task);
1788 gssize count_written;
1789  
1790 if (g_task_return_error_if_cancelled (task))
1791 return;
1792  
1793 count_written = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->
1794 write_nonblocking (stream, op->buffer, op->count_requested, &error);
1795  
1796 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
1797 {
1798 GSource *source;
1799  
1800 g_error_free (error);
1801  
1802 source = g_pollable_output_stream_create_source (stream,
1803 g_task_get_cancellable (task));
1804 g_task_attach_source (task, source,
1805 (GSourceFunc) write_async_pollable_ready);
1806 g_source_unref (source);
1807 return;
1808 }
1809  
1810 if (count_written == -1)
1811 g_task_return_error (task, error);
1812 else
1813 g_task_return_int (task, count_written);
1814 }
1815  
1816 static void
1817 g_output_stream_real_write_async (GOutputStream *stream,
1818 const void *buffer,
1819 gsize count,
1820 int io_priority,
1821 GCancellable *cancellable,
1822 GAsyncReadyCallback callback,
1823 gpointer user_data)
1824 {
1825 GTask *task;
1826 WriteData *op;
1827  
1828 op = g_slice_new0 (WriteData);
1829 task = g_task_new (stream, cancellable, callback, user_data);
1830 g_task_set_check_cancellable (task, FALSE);
1831 g_task_set_task_data (task, op, (GDestroyNotify) free_write_data);
1832 op->buffer = buffer;
1833 op->count_requested = count;
1834  
1835 if (!g_output_stream_async_write_is_via_threads (stream))
1836 write_async_pollable (G_POLLABLE_OUTPUT_STREAM (stream), task);
1837 else
1838 g_task_run_in_thread (task, write_async_thread);
1839 g_object_unref (task);
1840 }
1841  
1842 static gssize
1843 g_output_stream_real_write_finish (GOutputStream *stream,
1844 GAsyncResult *result,
1845 GError **error)
1846 {
1847 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1848  
1849 return g_task_propagate_int (G_TASK (result), error);
1850 }
1851  
1852 typedef struct {
1853 GInputStream *source;
1854 GOutputStreamSpliceFlags flags;
1855 gssize n_read;
1856 gssize n_written;
1857 gsize bytes_copied;
1858 GError *error;
1859 guint8 *buffer;
1860 } SpliceData;
1861  
1862 static void
1863 free_splice_data (SpliceData *op)
1864 {
1865 g_clear_pointer (&op->buffer, g_free);
1866 g_object_unref (op->source);
1867 g_clear_error (&op->error);
1868 g_free (op);
1869 }
1870  
1871 static void
1872 real_splice_async_complete_cb (GTask *task)
1873 {
1874 SpliceData *op = g_task_get_task_data (task);
1875  
1876 if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE &&
1877 !g_input_stream_is_closed (op->source))
1878 return;
1879  
1880 if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET &&
1881 !g_output_stream_is_closed (g_task_get_source_object (task)))
1882 return;
1883  
1884 if (op->error != NULL)
1885 {
1886 g_task_return_error (task, op->error);
1887 op->error = NULL;
1888 }
1889 else
1890 {
1891 g_task_return_int (task, op->bytes_copied);
1892 }
1893  
1894 g_object_unref (task);
1895 }
1896  
1897 static void
1898 real_splice_async_close_input_cb (GObject *source,
1899 GAsyncResult *res,
1900 gpointer user_data)
1901 {
1902 GTask *task = user_data;
1903  
1904 g_input_stream_close_finish (G_INPUT_STREAM (source), res, NULL);
1905  
1906 real_splice_async_complete_cb (task);
1907 }
1908  
1909 static void
1910 real_splice_async_close_output_cb (GObject *source,
1911 GAsyncResult *res,
1912 gpointer user_data)
1913 {
1914 GTask *task = G_TASK (user_data);
1915 SpliceData *op = g_task_get_task_data (task);
1916 GError **error = (op->error == NULL) ? &op->error : NULL;
1917  
1918 g_output_stream_internal_close_finish (G_OUTPUT_STREAM (source), res, error);
1919  
1920 real_splice_async_complete_cb (task);
1921 }
1922  
1923 static void
1924 real_splice_async_complete (GTask *task)
1925 {
1926 SpliceData *op = g_task_get_task_data (task);
1927 gboolean done = TRUE;
1928  
1929 if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
1930 {
1931 done = FALSE;
1932 g_input_stream_close_async (op->source, g_task_get_priority (task),
1933 g_task_get_cancellable (task),
1934 real_splice_async_close_input_cb, task);
1935 }
1936  
1937 if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
1938 {
1939 done = FALSE;
1940 g_output_stream_internal_close_async (g_task_get_source_object (task),
1941 g_task_get_priority (task),
1942 g_task_get_cancellable (task),
1943 real_splice_async_close_output_cb,
1944 task);
1945 }
1946  
1947 if (done)
1948 real_splice_async_complete_cb (task);
1949 }
1950  
1951 static void real_splice_async_read_cb (GObject *source,
1952 GAsyncResult *res,
1953 gpointer user_data);
1954  
1955 static void
1956 real_splice_async_write_cb (GObject *source,
1957 GAsyncResult *res,
1958 gpointer user_data)
1959 {
1960 GOutputStreamClass *class;
1961 GTask *task = G_TASK (user_data);
1962 SpliceData *op = g_task_get_task_data (task);
1963 gssize ret;
1964  
1965 class = G_OUTPUT_STREAM_GET_CLASS (g_task_get_source_object (task));
1966  
1967 ret = class->write_finish (G_OUTPUT_STREAM (source), res, &op->error);
1968  
1969 if (ret == -1)
1970 {
1971 real_splice_async_complete (task);
1972 return;
1973 }
1974  
1975 op->n_written += ret;
1976 op->bytes_copied += ret;
1977 if (op->bytes_copied > G_MAXSSIZE)
1978 op->bytes_copied = G_MAXSSIZE;
1979  
1980 if (op->n_written < op->n_read)
1981 {
1982 class->write_async (g_task_get_source_object (task),
1983 op->buffer + op->n_written,
1984 op->n_read - op->n_written,
1985 g_task_get_priority (task),
1986 g_task_get_cancellable (task),
1987 real_splice_async_write_cb, task);
1988 return;
1989 }
1990  
1991 g_input_stream_read_async (op->source, op->buffer, 8192,
1992 g_task_get_priority (task),
1993 g_task_get_cancellable (task),
1994 real_splice_async_read_cb, task);
1995 }
1996  
1997 static void
1998 real_splice_async_read_cb (GObject *source,
1999 GAsyncResult *res,
2000 gpointer user_data)
2001 {
2002 GOutputStreamClass *class;
2003 GTask *task = G_TASK (user_data);
2004 SpliceData *op = g_task_get_task_data (task);
2005 gssize ret;
2006  
2007 class = G_OUTPUT_STREAM_GET_CLASS (g_task_get_source_object (task));
2008  
2009 ret = g_input_stream_read_finish (op->source, res, &op->error);
2010 if (ret == -1 || ret == 0)
2011 {
2012 real_splice_async_complete (task);
2013 return;
2014 }
2015  
2016 op->n_read = ret;
2017 op->n_written = 0;
2018  
2019 class->write_async (g_task_get_source_object (task), op->buffer,
2020 op->n_read, g_task_get_priority (task),
2021 g_task_get_cancellable (task),
2022 real_splice_async_write_cb, task);
2023 }
2024  
2025 static void
2026 splice_async_thread (GTask *task,
2027 gpointer source_object,
2028 gpointer task_data,
2029 GCancellable *cancellable)
2030 {
2031 GOutputStream *stream = source_object;
2032 SpliceData *op = task_data;
2033 GOutputStreamClass *class;
2034 GError *error = NULL;
2035 gssize bytes_copied;
2036  
2037 class = G_OUTPUT_STREAM_GET_CLASS (stream);
2038  
2039 bytes_copied = class->splice (stream,
2040 op->source,
2041 op->flags,
2042 cancellable,
2043 &error);
2044 if (bytes_copied == -1)
2045 g_task_return_error (task, error);
2046 else
2047 g_task_return_int (task, bytes_copied);
2048 }
2049  
2050 static void
2051 g_output_stream_real_splice_async (GOutputStream *stream,
2052 GInputStream *source,
2053 GOutputStreamSpliceFlags flags,
2054 int io_priority,
2055 GCancellable *cancellable,
2056 GAsyncReadyCallback callback,
2057 gpointer user_data)
2058 {
2059 GTask *task;
2060 SpliceData *op;
2061  
2062 op = g_new0 (SpliceData, 1);
2063 task = g_task_new (stream, cancellable, callback, user_data);
2064 g_task_set_task_data (task, op, (GDestroyNotify)free_splice_data);
2065 op->flags = flags;
2066 op->source = g_object_ref (source);
2067  
2068 if (g_input_stream_async_read_is_via_threads (source) &&
2069 g_output_stream_async_write_is_via_threads (stream))
2070 {
2071 g_task_run_in_thread (task, splice_async_thread);
2072 g_object_unref (task);
2073 }
2074 else
2075 {
2076 op->buffer = g_malloc (8192);
2077 g_input_stream_read_async (op->source, op->buffer, 8192,
2078 g_task_get_priority (task),
2079 g_task_get_cancellable (task),
2080 real_splice_async_read_cb, task);
2081 }
2082 }
2083  
2084 static gssize
2085 g_output_stream_real_splice_finish (GOutputStream *stream,
2086 GAsyncResult *result,
2087 GError **error)
2088 {
2089 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
2090  
2091 return g_task_propagate_int (G_TASK (result), error);
2092 }
2093  
2094  
2095 static void
2096 flush_async_thread (GTask *task,
2097 gpointer source_object,
2098 gpointer task_data,
2099 GCancellable *cancellable)
2100 {
2101 GOutputStream *stream = source_object;
2102 GOutputStreamClass *class;
2103 gboolean result;
2104 GError *error = NULL;
2105  
2106 class = G_OUTPUT_STREAM_GET_CLASS (stream);
2107 result = TRUE;
2108 if (class->flush)
2109 result = class->flush (stream, cancellable, &error);
2110  
2111 if (result)
2112 g_task_return_boolean (task, TRUE);
2113 else
2114 g_task_return_error (task, error);
2115 }
2116  
2117 static void
2118 g_output_stream_real_flush_async (GOutputStream *stream,
2119 int io_priority,
2120 GCancellable *cancellable,
2121 GAsyncReadyCallback callback,
2122 gpointer user_data)
2123 {
2124 GTask *task;
2125  
2126 task = g_task_new (stream, cancellable, callback, user_data);
2127 g_task_set_priority (task, io_priority);
2128 g_task_run_in_thread (task, flush_async_thread);
2129 g_object_unref (task);
2130 }
2131  
2132 static gboolean
2133 g_output_stream_real_flush_finish (GOutputStream *stream,
2134 GAsyncResult *result,
2135 GError **error)
2136 {
2137 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
2138  
2139 return g_task_propagate_boolean (G_TASK (result), error);
2140 }
2141  
2142 static void
2143 close_async_thread (GTask *task,
2144 gpointer source_object,
2145 gpointer task_data,
2146 GCancellable *cancellable)
2147 {
2148 GOutputStream *stream = source_object;
2149 GOutputStreamClass *class;
2150 GError *error = NULL;
2151 gboolean result = TRUE;
2152  
2153 class = G_OUTPUT_STREAM_GET_CLASS (stream);
2154  
2155 /* Do a flush here if there is a flush function, and we did not have to do
2156 * an async flush before (see g_output_stream_close_async)
2157 */
2158 if (class->flush != NULL &&
2159 (class->flush_async == NULL ||
2160 class->flush_async == g_output_stream_real_flush_async))
2161 {
2162 result = class->flush (stream, cancellable, &error);
2163 }
2164  
2165 /* Auto handling of cancelation disabled, and ignore
2166 cancellation, since we want to close things anyway, although
2167 possibly in a quick-n-dirty way. At least we never want to leak
2168 open handles */
2169  
2170 if (class->close_fn)
2171 {
2172 /* Make sure to close, even if the flush failed (see sync close) */
2173 if (!result)
2174 class->close_fn (stream, cancellable, NULL);
2175 else
2176 result = class->close_fn (stream, cancellable, &error);
2177 }
2178  
2179 if (result)
2180 g_task_return_boolean (task, TRUE);
2181 else
2182 g_task_return_error (task, error);
2183 }
2184  
2185 static void
2186 g_output_stream_real_close_async (GOutputStream *stream,
2187 int io_priority,
2188 GCancellable *cancellable,
2189 GAsyncReadyCallback callback,
2190 gpointer user_data)
2191 {
2192 GTask *task;
2193  
2194 task = g_task_new (stream, cancellable, callback, user_data);
2195 g_task_set_priority (task, io_priority);
2196 g_task_run_in_thread (task, close_async_thread);
2197 g_object_unref (task);
2198 }
2199  
2200 static gboolean
2201 g_output_stream_real_close_finish (GOutputStream *stream,
2202 GAsyncResult *result,
2203 GError **error)
2204 {
2205 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
2206  
2207 return g_task_propagate_boolean (G_TASK (result), error);
2208 }