Spelling fixes
[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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include "config.h"
24 #include "goutputstream.h"
25 #include "gcancellable.h"
26 #include "gasyncresult.h"
27 #include "gsimpleasyncresult.h"
28 #include "ginputstream.h"
29 #include "gioerror.h"
30 #include "glibintl.h"
31
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  * All of these functions have async variants too.
46  **/
47
48 G_DEFINE_ABSTRACT_TYPE (GOutputStream, g_output_stream, G_TYPE_OBJECT);
49
50 struct _GOutputStreamPrivate {
51   guint closed : 1;
52   guint pending : 1;
53   guint closing : 1;
54   GAsyncReadyCallback outstanding_callback;
55 };
56
57 static gssize   g_output_stream_real_splice        (GOutputStream             *stream,
58                                                     GInputStream              *source,
59                                                     GOutputStreamSpliceFlags   flags,
60                                                     GCancellable              *cancellable,
61                                                     GError                   **error);
62 static void     g_output_stream_real_write_async   (GOutputStream             *stream,
63                                                     const void                *buffer,
64                                                     gsize                      count,
65                                                     int                        io_priority,
66                                                     GCancellable              *cancellable,
67                                                     GAsyncReadyCallback        callback,
68                                                     gpointer                   data);
69 static gssize   g_output_stream_real_write_finish  (GOutputStream             *stream,
70                                                     GAsyncResult              *result,
71                                                     GError                   **error);
72 static void     g_output_stream_real_splice_async  (GOutputStream             *stream,
73                                                     GInputStream              *source,
74                                                     GOutputStreamSpliceFlags   flags,
75                                                     int                        io_priority,
76                                                     GCancellable              *cancellable,
77                                                     GAsyncReadyCallback        callback,
78                                                     gpointer                   data);
79 static gssize   g_output_stream_real_splice_finish (GOutputStream             *stream,
80                                                     GAsyncResult              *result,
81                                                     GError                   **error);
82 static void     g_output_stream_real_flush_async   (GOutputStream             *stream,
83                                                     int                        io_priority,
84                                                     GCancellable              *cancellable,
85                                                     GAsyncReadyCallback        callback,
86                                                     gpointer                   data);
87 static gboolean g_output_stream_real_flush_finish  (GOutputStream             *stream,
88                                                     GAsyncResult              *result,
89                                                     GError                   **error);
90 static void     g_output_stream_real_close_async   (GOutputStream             *stream,
91                                                     int                        io_priority,
92                                                     GCancellable              *cancellable,
93                                                     GAsyncReadyCallback        callback,
94                                                     gpointer                   data);
95 static gboolean g_output_stream_real_close_finish  (GOutputStream             *stream,
96                                                     GAsyncResult              *result,
97                                                     GError                   **error);
98
99 static void
100 g_output_stream_finalize (GObject *object)
101 {
102   G_OBJECT_CLASS (g_output_stream_parent_class)->finalize (object);
103 }
104
105 static void
106 g_output_stream_dispose (GObject *object)
107 {
108   GOutputStream *stream;
109
110   stream = G_OUTPUT_STREAM (object);
111   
112   if (!stream->priv->closed)
113     g_output_stream_close (stream, NULL, NULL);
114
115   G_OBJECT_CLASS (g_output_stream_parent_class)->dispose (object);
116 }
117
118 static void
119 g_output_stream_class_init (GOutputStreamClass *klass)
120 {
121   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
122   
123   g_type_class_add_private (klass, sizeof (GOutputStreamPrivate));
124   
125   gobject_class->finalize = g_output_stream_finalize;
126   gobject_class->dispose = g_output_stream_dispose;
127
128   klass->splice = g_output_stream_real_splice;
129   
130   klass->write_async = g_output_stream_real_write_async;
131   klass->write_finish = g_output_stream_real_write_finish;
132   klass->splice_async = g_output_stream_real_splice_async;
133   klass->splice_finish = g_output_stream_real_splice_finish;
134   klass->flush_async = g_output_stream_real_flush_async;
135   klass->flush_finish = g_output_stream_real_flush_finish;
136   klass->close_async = g_output_stream_real_close_async;
137   klass->close_finish = g_output_stream_real_close_finish;
138 }
139
140 static void
141 g_output_stream_init (GOutputStream *stream)
142 {
143   stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
144                                               G_TYPE_OUTPUT_STREAM,
145                                               GOutputStreamPrivate);
146 }
147
148 /**
149  * g_output_stream_write:
150  * @stream: a #GOutputStream.
151  * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. 
152  * @count: the number of bytes to write
153  * @cancellable: (allow-none): optional cancellable object
154  * @error: location to store the error occurring, or %NULL to ignore
155  *
156  * Tries to write @count bytes from @buffer into the stream. Will block
157  * during the operation.
158  * 
159  * If count is 0, returns 0 and does nothing. A value of @count
160  * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
161  *
162  * On success, the number of bytes written to the stream is returned.
163  * It is not an error if this is not the same as the requested size, as it
164  * can happen e.g. on a partial I/O error, or if there is not enough
165  * storage in the stream. All writes block until at least one byte
166  * is written or an error occurs; 0 is never returned (unless
167  * @count is 0).
168  * 
169  * If @cancellable is not NULL, then the operation can be cancelled by
170  * triggering the cancellable object from another thread. If the operation
171  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
172  * operation was partially finished when the operation was cancelled the
173  * partial result will be returned, without an error.
174  *
175  * On error -1 is returned and @error is set accordingly.
176  * 
177  * Return value: Number of bytes written, or -1 on error
178  **/
179 gssize
180 g_output_stream_write (GOutputStream  *stream,
181                        const void     *buffer,
182                        gsize           count,
183                        GCancellable   *cancellable,
184                        GError        **error)
185 {
186   GOutputStreamClass *class;
187   gssize res;
188
189   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
190   g_return_val_if_fail (buffer != NULL, 0);
191
192   if (count == 0)
193     return 0;
194   
195   if (((gssize) count) < 0)
196     {
197       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
198                    _("Too large count value passed to %s"), G_STRFUNC);
199       return -1;
200     }
201
202   class = G_OUTPUT_STREAM_GET_CLASS (stream);
203
204   if (class->write_fn == NULL) 
205     {
206       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
207                            _("Output stream doesn't implement write"));
208       return -1;
209     }
210   
211   if (!g_output_stream_set_pending (stream, error))
212     return -1;
213   
214   if (cancellable)
215     g_cancellable_push_current (cancellable);
216   
217   res = class->write_fn (stream, buffer, count, cancellable, error);
218   
219   if (cancellable)
220     g_cancellable_pop_current (cancellable);
221   
222   g_output_stream_clear_pending (stream);
223
224   return res; 
225 }
226
227 /**
228  * g_output_stream_write_all:
229  * @stream: a #GOutputStream.
230  * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. 
231  * @count: the number of bytes to write
232  * @bytes_written: (out): location to store the number of bytes that was 
233  *     written to the stream
234  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
235  * @error: location to store the error occurring, or %NULL to ignore
236  *
237  * Tries to write @count bytes from @buffer into the stream. Will block
238  * during the operation.
239  * 
240  * This function is similar to g_output_stream_write(), except it tries to
241  * write as many bytes as requested, only stopping on an error.
242  *
243  * On a successful write of @count bytes, %TRUE is returned, and @bytes_written
244  * is set to @count.
245  * 
246  * If there is an error during the operation FALSE is returned and @error
247  * is set to indicate the error status, @bytes_written is updated to contain
248  * the number of bytes written into the stream before the error occurred.
249  *
250  * Return value: %TRUE on success, %FALSE if there was an error
251  **/
252 gboolean
253 g_output_stream_write_all (GOutputStream  *stream,
254                            const void     *buffer,
255                            gsize           count,
256                            gsize          *bytes_written,
257                            GCancellable   *cancellable,
258                            GError        **error)
259 {
260   gsize _bytes_written;
261   gssize res;
262
263   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
264   g_return_val_if_fail (buffer != NULL, FALSE);
265
266   _bytes_written = 0;
267   while (_bytes_written < count)
268     {
269       res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written,
270                                    cancellable, error);
271       if (res == -1)
272         {
273           if (bytes_written)
274             *bytes_written = _bytes_written;
275           return FALSE;
276         }
277       
278       if (res == 0)
279         g_warning ("Write returned zero without error");
280
281       _bytes_written += res;
282     }
283   
284   if (bytes_written)
285     *bytes_written = _bytes_written;
286
287   return TRUE;
288 }
289
290 /**
291  * g_output_stream_flush:
292  * @stream: a #GOutputStream.
293  * @cancellable: (allow-none): optional cancellable object
294  * @error: location to store the error occurring, or %NULL to ignore
295  *
296  * Flushed any outstanding buffers in the stream. Will block during 
297  * the operation. Closing the stream will implicitly cause a flush.
298  *
299  * This function is optional for inherited classes.
300  * 
301  * If @cancellable is not %NULL, then the operation can be cancelled by
302  * triggering the cancellable object from another thread. If the operation
303  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
304  *
305  * Return value: %TRUE on success, %FALSE on error
306  **/
307 gboolean
308 g_output_stream_flush (GOutputStream  *stream,
309                        GCancellable   *cancellable,
310                        GError        **error)
311 {
312   GOutputStreamClass *class;
313   gboolean res;
314
315   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
316
317   if (!g_output_stream_set_pending (stream, error))
318     return FALSE;
319   
320   class = G_OUTPUT_STREAM_GET_CLASS (stream);
321
322   res = TRUE;
323   if (class->flush)
324     {
325       if (cancellable)
326         g_cancellable_push_current (cancellable);
327       
328       res = class->flush (stream, cancellable, error);
329       
330       if (cancellable)
331         g_cancellable_pop_current (cancellable);
332     }
333   
334   g_output_stream_clear_pending (stream);
335
336   return res;
337 }
338
339 /**
340  * g_output_stream_splice:
341  * @stream: a #GOutputStream.
342  * @source: a #GInputStream.
343  * @flags: a set of #GOutputStreamSpliceFlags.
344  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
345  * @error: a #GError location to store the error occurring, or %NULL to
346  * ignore.
347  *
348  * Splices an input stream into an output stream.
349  *
350  * Returns: a #gssize containing the size of the data spliced, or
351  *     -1 if an error occurred. Note that if the number of bytes
352  *     spliced is greater than %G_MAXSSIZE, then that will be
353  *     returned, and there is no way to determine the actual number
354  *     of bytes spliced.
355  **/
356 gssize
357 g_output_stream_splice (GOutputStream             *stream,
358                         GInputStream              *source,
359                         GOutputStreamSpliceFlags   flags,
360                         GCancellable              *cancellable,
361                         GError                   **error)
362 {
363   GOutputStreamClass *class;
364   gssize bytes_copied;
365
366   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
367   g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1);
368
369   if (g_input_stream_is_closed (source))
370     {
371       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
372                            _("Source stream is already closed"));
373       return -1;
374     }
375
376   if (!g_output_stream_set_pending (stream, error))
377     return -1;
378
379   class = G_OUTPUT_STREAM_GET_CLASS (stream);
380
381   if (cancellable)
382     g_cancellable_push_current (cancellable);
383
384   bytes_copied = class->splice (stream, source, flags, cancellable, error);
385
386   if (cancellable)
387     g_cancellable_pop_current (cancellable);
388
389   g_output_stream_clear_pending (stream);
390
391   return bytes_copied;
392 }
393
394 static gssize
395 g_output_stream_real_splice (GOutputStream             *stream,
396                              GInputStream              *source,
397                              GOutputStreamSpliceFlags   flags,
398                              GCancellable              *cancellable,
399                              GError                   **error)
400 {
401   GOutputStreamClass *class = G_OUTPUT_STREAM_GET_CLASS (stream);
402   gssize n_read, n_written;
403   gsize bytes_copied;
404   char buffer[8192], *p;
405   gboolean res;
406
407   bytes_copied = 0;
408   if (class->write_fn == NULL)
409     {
410       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
411                            _("Output stream doesn't implement write"));
412       res = FALSE;
413       goto notsupported;
414     }
415
416   res = TRUE;
417   do
418     {
419       n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error);
420       if (n_read == -1)
421         {
422           res = FALSE;
423           break;
424         }
425
426       if (n_read == 0)
427         break;
428
429       p = buffer;
430       while (n_read > 0)
431         {
432           n_written = class->write_fn (stream, p, n_read, cancellable, error);
433           if (n_written == -1)
434             {
435               res = FALSE;
436               break;
437             }
438
439           p += n_written;
440           n_read -= n_written;
441           bytes_copied += n_written;
442         }
443
444       if (bytes_copied > G_MAXSSIZE)
445         bytes_copied = G_MAXSSIZE;
446     }
447   while (res);
448
449  notsupported:
450   if (!res)
451     error = NULL; /* Ignore further errors */
452
453   if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
454     {
455       /* Don't care about errors in source here */
456       g_input_stream_close (source, cancellable, NULL);
457     }
458
459   if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
460     {
461       /* But write errors on close are bad! */
462       if (class->close_fn &&
463           !class->close_fn (stream, cancellable, error))
464         res = FALSE;
465     }
466
467   if (res)
468     return bytes_copied;
469
470   return -1;
471 }
472
473
474 /**
475  * g_output_stream_close:
476  * @stream: A #GOutputStream.
477  * @cancellable: (allow-none): optional cancellable object
478  * @error: location to store the error occurring, or %NULL to ignore
479  *
480  * Closes the stream, releasing resources related to it.
481  *
482  * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
483  * Closing a stream multiple times will not return an error.
484  *
485  * Closing a stream will automatically flush any outstanding buffers in the
486  * stream.
487  *
488  * Streams will be automatically closed when the last reference
489  * is dropped, but you might want to call this function to make sure 
490  * resources are released as early as possible.
491  *
492  * Some streams might keep the backing store of the stream (e.g. a file descriptor)
493  * open after the stream is closed. See the documentation for the individual
494  * stream for details.
495  *
496  * On failure the first error that happened will be reported, but the close
497  * operation will finish as much as possible. A stream that failed to
498  * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it
499  * is important to check and report the error to the user, otherwise
500  * there might be a loss of data as all data might not be written.
501  * 
502  * If @cancellable is not NULL, then the operation can be cancelled by
503  * triggering the cancellable object from another thread. If the operation
504  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
505  * Cancelling a close will still leave the stream closed, but there some streams
506  * can use a faster close that doesn't block to e.g. check errors. On
507  * cancellation (as with any error) there is no guarantee that all written
508  * data will reach the target. 
509  *
510  * Return value: %TRUE on success, %FALSE on failure
511  **/
512 gboolean
513 g_output_stream_close (GOutputStream  *stream,
514                        GCancellable   *cancellable,
515                        GError        **error)
516 {
517   GOutputStreamClass *class;
518   gboolean res;
519
520   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
521
522   class = G_OUTPUT_STREAM_GET_CLASS (stream);
523
524   if (stream->priv->closed)
525     return TRUE;
526
527   if (!g_output_stream_set_pending (stream, error))
528     return FALSE;
529
530   stream->priv->closing = TRUE;
531
532   if (cancellable)
533     g_cancellable_push_current (cancellable);
534
535   if (class->flush)
536     res = class->flush (stream, cancellable, error);
537   else
538     res = TRUE;
539   
540   if (!res)
541     {
542       /* flushing caused the error that we want to return,
543        * but we still want to close the underlying stream if possible
544        */
545       if (class->close_fn)
546         class->close_fn (stream, cancellable, NULL);
547     }
548   else
549     {
550       res = TRUE;
551       if (class->close_fn)
552         res = class->close_fn (stream, cancellable, error);
553     }
554   
555   if (cancellable)
556     g_cancellable_pop_current (cancellable);
557
558   stream->priv->closing = FALSE;
559   stream->priv->closed = TRUE;
560   g_output_stream_clear_pending (stream);
561   
562   return res;
563 }
564
565 static void
566 async_ready_callback_wrapper (GObject      *source_object,
567                               GAsyncResult *res,
568                               gpointer      user_data)
569 {
570   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
571
572   g_output_stream_clear_pending (stream);
573   if (stream->priv->outstanding_callback)
574     (*stream->priv->outstanding_callback) (source_object, res, user_data);
575   g_object_unref (stream);
576 }
577
578 typedef struct {
579   gint io_priority;
580   GCancellable *cancellable;
581   GError *flush_error;
582   gpointer user_data;
583 } CloseUserData;
584
585 static void
586 async_ready_close_callback_wrapper (GObject      *source_object,
587                                     GAsyncResult *res,
588                                     gpointer      user_data)
589 {
590   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
591   CloseUserData *data = user_data;
592
593   stream->priv->closing = FALSE;
594   stream->priv->closed = TRUE;
595
596   g_output_stream_clear_pending (stream);
597
598   if (stream->priv->outstanding_callback)
599     {
600       if (data->flush_error != NULL)
601         {
602           GSimpleAsyncResult *err;
603
604           err = g_simple_async_result_new_take_error (source_object,
605                                                       stream->priv->outstanding_callback,
606                                                       data->user_data,
607                                                       data->flush_error);
608           data->flush_error = NULL;
609
610           (*stream->priv->outstanding_callback) (source_object,
611                                                  G_ASYNC_RESULT (err),
612                                                  data->user_data);
613           g_object_unref (err);
614         }
615       else
616         {
617           (*stream->priv->outstanding_callback) (source_object,
618                                                  res,
619                                                  data->user_data);
620         }
621     }
622
623   g_object_unref (stream);
624
625   if (data->cancellable)
626     g_object_unref (data->cancellable);
627
628   if (data->flush_error)
629     g_error_free (data->flush_error);
630
631   g_slice_free (CloseUserData, data);
632 }
633
634 static void
635 async_ready_close_flushed_callback_wrapper (GObject      *source_object,
636                                             GAsyncResult *res,
637                                             gpointer      user_data)
638 {
639   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
640   GOutputStreamClass *class;
641   CloseUserData *data = user_data;
642   GSimpleAsyncResult *simple;
643
644   /* propagate the possible error */
645   if (G_IS_SIMPLE_ASYNC_RESULT (res))
646     {
647       simple = G_SIMPLE_ASYNC_RESULT (res);
648       g_simple_async_result_propagate_error (simple, &data->flush_error);
649     }
650
651   class = G_OUTPUT_STREAM_GET_CLASS (stream);
652
653   /* we still close, even if there was a flush error */
654   class->close_async (stream, data->io_priority, data->cancellable,
655                       async_ready_close_callback_wrapper, user_data);
656 }
657
658 /**
659  * g_output_stream_write_async:
660  * @stream: A #GOutputStream.
661  * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. 
662  * @count: the number of bytes to write
663  * @io_priority: the io priority of the request.
664  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
665  * @callback: (scope async): callback to call when the request is satisfied
666  * @user_data: (closure): the data to pass to callback function
667  *
668  * Request an asynchronous write of @count bytes from @buffer into 
669  * the stream. When the operation is finished @callback will be called.
670  * You can then call g_output_stream_write_finish() to get the result of the 
671  * operation.
672  *
673  * During an async request no other sync and async calls are allowed, 
674  * and will result in %G_IO_ERROR_PENDING errors. 
675  *
676  * A value of @count larger than %G_MAXSSIZE will cause a 
677  * %G_IO_ERROR_INVALID_ARGUMENT error.
678  *
679  * On success, the number of bytes written will be passed to the
680  * @callback. It is not an error if this is not the same as the 
681  * requested size, as it can happen e.g. on a partial I/O error, 
682  * but generally we try to write as many bytes as requested. 
683  *
684  * You are guaranteed that this method will never fail with
685  * %G_IO_ERROR_WOULD_BLOCK - if @stream can't accept more data, the
686  * method will just wait until this changes.
687  *
688  * Any outstanding I/O request with higher priority (lower numerical 
689  * value) will be executed before an outstanding request with lower 
690  * priority. Default priority is %G_PRIORITY_DEFAULT.
691  *
692  * The asyncronous methods have a default fallback that uses threads 
693  * to implement asynchronicity, so they are optional for inheriting 
694  * classes. However, if you override one you must override all.
695  *
696  * For the synchronous, blocking version of this function, see 
697  * g_output_stream_write().
698  **/
699 void
700 g_output_stream_write_async (GOutputStream       *stream,
701                              const void          *buffer,
702                              gsize                count,
703                              int                  io_priority,
704                              GCancellable        *cancellable,
705                              GAsyncReadyCallback  callback,
706                              gpointer             user_data)
707 {
708   GOutputStreamClass *class;
709   GSimpleAsyncResult *simple;
710   GError *error = NULL;
711
712   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
713   g_return_if_fail (buffer != NULL);
714
715   if (count == 0)
716     {
717       simple = g_simple_async_result_new (G_OBJECT (stream),
718                                           callback,
719                                           user_data,
720                                           g_output_stream_write_async);
721       g_simple_async_result_complete_in_idle (simple);
722       g_object_unref (simple);
723       return;
724     }
725
726   if (((gssize) count) < 0)
727     {
728       g_simple_async_report_error_in_idle (G_OBJECT (stream),
729                                            callback,
730                                            user_data,
731                                            G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
732                                            _("Too large count value passed to %s"),
733                                            G_STRFUNC);
734       return;
735     }
736
737   if (!g_output_stream_set_pending (stream, &error))
738     {
739       g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
740                                             callback,
741                                             user_data,
742                                             error);
743       return;
744     }
745   
746   class = G_OUTPUT_STREAM_GET_CLASS (stream);
747
748   stream->priv->outstanding_callback = callback;
749   g_object_ref (stream);
750   class->write_async (stream, buffer, count, io_priority, cancellable,
751                       async_ready_callback_wrapper, user_data);
752 }
753
754 /**
755  * g_output_stream_write_finish:
756  * @stream: a #GOutputStream.
757  * @result: a #GAsyncResult.
758  * @error: a #GError location to store the error occurring, or %NULL to 
759  * ignore.
760  * 
761  * Finishes a stream write operation.
762  * 
763  * Returns: a #gssize containing the number of bytes written to the stream.
764  **/
765 gssize
766 g_output_stream_write_finish (GOutputStream  *stream,
767                               GAsyncResult   *result,
768                               GError        **error)
769 {
770   GSimpleAsyncResult *simple;
771   GOutputStreamClass *class;
772
773   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
774   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
775
776   if (G_IS_SIMPLE_ASYNC_RESULT (result))
777     {
778       simple = G_SIMPLE_ASYNC_RESULT (result);
779       if (g_simple_async_result_propagate_error (simple, error))
780         return -1;
781
782       /* Special case writes of 0 bytes */
783       if (g_simple_async_result_get_source_tag (simple) == g_output_stream_write_async)
784         return 0;
785     }
786   
787   class = G_OUTPUT_STREAM_GET_CLASS (stream);
788   return class->write_finish (stream, result, error);
789 }
790
791 typedef struct {
792   GInputStream *source;
793   gpointer user_data;
794   GAsyncReadyCallback callback;
795 } SpliceUserData;
796
797 static void
798 async_ready_splice_callback_wrapper (GObject      *source_object,
799                                      GAsyncResult *res,
800                                      gpointer     _data)
801 {
802   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
803   SpliceUserData *data = _data;
804   
805   g_output_stream_clear_pending (stream);
806   
807   if (data->callback)
808     (*data->callback) (source_object, res, data->user_data);
809   
810   g_object_unref (stream);
811   g_object_unref (data->source);
812   g_free (data);
813 }
814
815 /**
816  * g_output_stream_splice_async:
817  * @stream: a #GOutputStream.
818  * @source: a #GInputStream. 
819  * @flags: a set of #GOutputStreamSpliceFlags.
820  * @io_priority: the io priority of the request.
821  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. 
822  * @callback: (scope async): a #GAsyncReadyCallback. 
823  * @user_data: (closure): user data passed to @callback.
824  * 
825  * Splices a stream asynchronously.
826  * When the operation is finished @callback will be called.
827  * You can then call g_output_stream_splice_finish() to get the 
828  * result of the operation.
829  *
830  * For the synchronous, blocking version of this function, see 
831  * g_output_stream_splice().
832  **/
833 void
834 g_output_stream_splice_async (GOutputStream            *stream,
835                               GInputStream             *source,
836                               GOutputStreamSpliceFlags  flags,
837                               int                       io_priority,
838                               GCancellable             *cancellable,
839                               GAsyncReadyCallback       callback,
840                               gpointer                  user_data)
841 {
842   GOutputStreamClass *class;
843   SpliceUserData *data;
844   GError *error = NULL;
845
846   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
847   g_return_if_fail (G_IS_INPUT_STREAM (source));
848
849   if (g_input_stream_is_closed (source))
850     {
851       g_simple_async_report_error_in_idle (G_OBJECT (stream),
852                                            callback,
853                                            user_data,
854                                            G_IO_ERROR, G_IO_ERROR_CLOSED,
855                                            _("Source stream is already closed"));
856       return;
857     }
858   
859   if (!g_output_stream_set_pending (stream, &error))
860     {
861       g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
862                                             callback,
863                                             user_data,
864                                             error);
865       return;
866     }
867
868   class = G_OUTPUT_STREAM_GET_CLASS (stream);
869
870   data = g_new0 (SpliceUserData, 1);
871   data->callback = callback;
872   data->user_data = user_data;
873   data->source = g_object_ref (source);
874   
875   g_object_ref (stream);
876   class->splice_async (stream, source, flags, io_priority, cancellable,
877                       async_ready_splice_callback_wrapper, data);
878 }
879
880 /**
881  * g_output_stream_splice_finish:
882  * @stream: a #GOutputStream.
883  * @result: a #GAsyncResult.
884  * @error: a #GError location to store the error occurring, or %NULL to 
885  * ignore.
886  *
887  * Finishes an asynchronous stream splice operation.
888  * 
889  * Returns: a #gssize of the number of bytes spliced. Note that if the
890  *     number of bytes spliced is greater than %G_MAXSSIZE, then that
891  *     will be returned, and there is no way to determine the actual
892  *     number of bytes spliced.
893  **/
894 gssize
895 g_output_stream_splice_finish (GOutputStream  *stream,
896                                GAsyncResult   *result,
897                                GError        **error)
898 {
899   GSimpleAsyncResult *simple;
900   GOutputStreamClass *class;
901
902   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
903   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
904
905   if (G_IS_SIMPLE_ASYNC_RESULT (result))
906     {
907       simple = G_SIMPLE_ASYNC_RESULT (result);
908       if (g_simple_async_result_propagate_error (simple, error))
909         return -1;
910     }
911   
912   class = G_OUTPUT_STREAM_GET_CLASS (stream);
913   return class->splice_finish (stream, result, error);
914 }
915
916 /**
917  * g_output_stream_flush_async:
918  * @stream: a #GOutputStream.
919  * @io_priority: the io priority of the request.
920  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
921  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
922  * @user_data: (closure): the data to pass to callback function
923  * 
924  * Flushes a stream asynchronously.
925  * For behaviour details see g_output_stream_flush().
926  *
927  * When the operation is finished @callback will be 
928  * called. You can then call g_output_stream_flush_finish() to get the 
929  * result of the operation.
930  **/
931 void
932 g_output_stream_flush_async (GOutputStream       *stream,
933                              int                  io_priority,
934                              GCancellable        *cancellable,
935                              GAsyncReadyCallback  callback,
936                              gpointer             user_data)
937 {
938   GOutputStreamClass *class;
939   GSimpleAsyncResult *simple;
940   GError *error = NULL;
941
942   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
943
944   if (!g_output_stream_set_pending (stream, &error))
945     {
946       g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
947                                             callback,
948                                             user_data,
949                                             error);
950       return;
951     }
952
953   stream->priv->outstanding_callback = callback;
954   g_object_ref (stream);
955
956   class = G_OUTPUT_STREAM_GET_CLASS (stream);
957   
958   if (class->flush_async == NULL)
959     {
960       simple = g_simple_async_result_new (G_OBJECT (stream),
961                                           async_ready_callback_wrapper,
962                                           user_data,
963                                           g_output_stream_flush_async);
964       g_simple_async_result_complete_in_idle (simple);
965       g_object_unref (simple);
966       return;
967     }
968       
969   class->flush_async (stream, io_priority, cancellable,
970                       async_ready_callback_wrapper, user_data);
971 }
972
973 /**
974  * g_output_stream_flush_finish:
975  * @stream: a #GOutputStream.
976  * @result: a GAsyncResult.
977  * @error: a #GError location to store the error occurring, or %NULL to 
978  * ignore.
979  * 
980  * Finishes flushing an output stream.
981  * 
982  * Returns: %TRUE if flush operation succeeded, %FALSE otherwise.
983  **/
984 gboolean
985 g_output_stream_flush_finish (GOutputStream  *stream,
986                               GAsyncResult   *result,
987                               GError        **error)
988 {
989   GSimpleAsyncResult *simple;
990   GOutputStreamClass *klass;
991
992   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
993   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
994
995   if (G_IS_SIMPLE_ASYNC_RESULT (result))
996     {
997       simple = G_SIMPLE_ASYNC_RESULT (result);
998       if (g_simple_async_result_propagate_error (simple, error))
999         return FALSE;
1000
1001       /* Special case default implementation */
1002       if (g_simple_async_result_get_source_tag (simple) == g_output_stream_flush_async)
1003         return TRUE;
1004     }
1005
1006   klass = G_OUTPUT_STREAM_GET_CLASS (stream);
1007   return klass->flush_finish (stream, result, error);
1008 }
1009
1010
1011 /**
1012  * g_output_stream_close_async:
1013  * @stream: A #GOutputStream.
1014  * @io_priority: the io priority of the request.
1015  * @cancellable: (allow-none): optional cancellable object
1016  * @callback: (scope async): callback to call when the request is satisfied
1017  * @user_data: (closure): the data to pass to callback function
1018  *
1019  * Requests an asynchronous close of the stream, releasing resources 
1020  * related to it. When the operation is finished @callback will be 
1021  * called. You can then call g_output_stream_close_finish() to get 
1022  * the result of the operation.
1023  *
1024  * For behaviour details see g_output_stream_close().
1025  *
1026  * The asyncronous methods have a default fallback that uses threads 
1027  * to implement asynchronicity, so they are optional for inheriting 
1028  * classes. However, if you override one you must override all.
1029  **/
1030 void
1031 g_output_stream_close_async (GOutputStream       *stream,
1032                              int                  io_priority,
1033                              GCancellable        *cancellable,
1034                              GAsyncReadyCallback  callback,
1035                              gpointer             user_data)
1036 {
1037   GOutputStreamClass *class;
1038   GSimpleAsyncResult *simple;
1039   GError *error = NULL;
1040   CloseUserData *data;
1041
1042   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1043   
1044   if (stream->priv->closed)
1045     {
1046       simple = g_simple_async_result_new (G_OBJECT (stream),
1047                                           callback,
1048                                           user_data,
1049                                           g_output_stream_close_async);
1050       g_simple_async_result_complete_in_idle (simple);
1051       g_object_unref (simple);
1052       return;
1053     }
1054
1055   if (!g_output_stream_set_pending (stream, &error))
1056     {
1057       g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
1058                                             callback,
1059                                             user_data,
1060                                             error);
1061       return;
1062     }
1063   
1064   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1065   stream->priv->closing = TRUE;
1066   stream->priv->outstanding_callback = callback;
1067   g_object_ref (stream);
1068
1069   data = g_slice_new0 (CloseUserData);
1070
1071   if (cancellable != NULL)
1072     data->cancellable = g_object_ref (cancellable);
1073
1074   data->io_priority = io_priority;
1075   data->user_data = user_data;
1076
1077   /* Call close_async directly if there is no need to flush, or if the flush
1078      can be done sync (in the output stream async close thread) */
1079   if (class->flush_async == NULL ||
1080       (class->flush_async == g_output_stream_real_flush_async &&
1081        (class->flush == NULL || class->close_async == g_output_stream_real_close_async)))
1082     {
1083       class->close_async (stream, io_priority, cancellable,
1084                           async_ready_close_callback_wrapper, data);
1085     }
1086   else
1087     {
1088       /* First do an async flush, then do the async close in the callback
1089          wrapper (see async_ready_close_flushed_callback_wrapper) */
1090       class->flush_async (stream, io_priority, cancellable,
1091                           async_ready_close_flushed_callback_wrapper, data);
1092     }
1093 }
1094
1095 /**
1096  * g_output_stream_close_finish:
1097  * @stream: a #GOutputStream.
1098  * @result: a #GAsyncResult.
1099  * @error: a #GError location to store the error occurring, or %NULL to 
1100  * ignore.
1101  * 
1102  * Closes an output stream.
1103  * 
1104  * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
1105  **/
1106 gboolean
1107 g_output_stream_close_finish (GOutputStream  *stream,
1108                               GAsyncResult   *result,
1109                               GError        **error)
1110 {
1111   GSimpleAsyncResult *simple;
1112   GOutputStreamClass *class;
1113
1114   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1115   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
1116
1117   if (G_IS_SIMPLE_ASYNC_RESULT (result))
1118     {
1119       simple = G_SIMPLE_ASYNC_RESULT (result);
1120       if (g_simple_async_result_propagate_error (simple, error))
1121         return FALSE;
1122
1123       /* Special case already closed */
1124       if (g_simple_async_result_get_source_tag (simple) == g_output_stream_close_async)
1125         return TRUE;
1126     }
1127
1128   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1129   return class->close_finish (stream, result, error);
1130 }
1131
1132 /**
1133  * g_output_stream_is_closed:
1134  * @stream: a #GOutputStream.
1135  * 
1136  * Checks if an output stream has already been closed.
1137  * 
1138  * Returns: %TRUE if @stream is closed. %FALSE otherwise. 
1139  **/
1140 gboolean
1141 g_output_stream_is_closed (GOutputStream *stream)
1142 {
1143   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1144   
1145   return stream->priv->closed;
1146 }
1147
1148 /**
1149  * g_output_stream_is_closing:
1150  * @stream: a #GOutputStream.
1151  *
1152  * Checks if an output stream is being closed. This can be
1153  * used inside e.g. a flush implementation to see if the
1154  * flush (or other i/o operation) is called from within
1155  * the closing operation.
1156  *
1157  * Returns: %TRUE if @stream is being closed. %FALSE otherwise.
1158  *
1159  * Since: 2.24
1160  **/
1161 gboolean
1162 g_output_stream_is_closing (GOutputStream *stream)
1163 {
1164   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1165
1166   return stream->priv->closing;
1167 }
1168
1169 /**
1170  * g_output_stream_has_pending:
1171  * @stream: a #GOutputStream.
1172  * 
1173  * Checks if an ouput stream has pending actions.
1174  * 
1175  * Returns: %TRUE if @stream has pending actions. 
1176  **/
1177 gboolean
1178 g_output_stream_has_pending (GOutputStream *stream)
1179 {
1180   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1181   
1182   return stream->priv->pending;
1183 }
1184
1185 /**
1186  * g_output_stream_set_pending:
1187  * @stream: a #GOutputStream.
1188  * @error: a #GError location to store the error occurring, or %NULL to 
1189  * ignore.
1190  * 
1191  * Sets @stream to have actions pending. If the pending flag is
1192  * already set or @stream is closed, it will return %FALSE and set
1193  * @error.
1194  *
1195  * Return value: %TRUE if pending was previously unset and is now set.
1196  **/
1197 gboolean
1198 g_output_stream_set_pending (GOutputStream *stream,
1199                              GError **error)
1200 {
1201   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1202   
1203   if (stream->priv->closed)
1204     {
1205       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1206                            _("Stream is already closed"));
1207       return FALSE;
1208     }
1209   
1210   if (stream->priv->pending)
1211     {
1212       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
1213                            /* Translators: This is an error you get if there is
1214                             * already an operation running against this stream when
1215                             * you try to start one */
1216                            _("Stream has outstanding operation"));
1217       return FALSE;
1218     }
1219   
1220   stream->priv->pending = TRUE;
1221   return TRUE;
1222 }
1223
1224 /**
1225  * g_output_stream_clear_pending:
1226  * @stream: output stream
1227  * 
1228  * Clears the pending flag on @stream.
1229  **/
1230 void
1231 g_output_stream_clear_pending (GOutputStream *stream)
1232 {
1233   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1234   
1235   stream->priv->pending = FALSE;
1236 }
1237
1238
1239 /********************************************
1240  *   Default implementation of async ops    *
1241  ********************************************/
1242
1243 typedef struct {
1244   const void         *buffer;
1245   gsize               count_requested;
1246   gssize              count_written;
1247 } WriteData;
1248
1249 static void
1250 write_async_thread (GSimpleAsyncResult *res,
1251                     GObject            *object,
1252                     GCancellable       *cancellable)
1253 {
1254   WriteData *op;
1255   GOutputStreamClass *class;
1256   GError *error = NULL;
1257
1258   class = G_OUTPUT_STREAM_GET_CLASS (object);
1259   op = g_simple_async_result_get_op_res_gpointer (res);
1260   op->count_written = class->write_fn (G_OUTPUT_STREAM (object), op->buffer, op->count_requested,
1261                                        cancellable, &error);
1262   if (op->count_written == -1)
1263     g_simple_async_result_take_error (res, error);
1264 }
1265
1266 static void
1267 g_output_stream_real_write_async (GOutputStream       *stream,
1268                                   const void          *buffer,
1269                                   gsize                count,
1270                                   int                  io_priority,
1271                                   GCancellable        *cancellable,
1272                                   GAsyncReadyCallback  callback,
1273                                   gpointer             user_data)
1274 {
1275   GSimpleAsyncResult *res;
1276   WriteData *op;
1277
1278   op = g_new0 (WriteData, 1);
1279   res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1280   g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1281   op->buffer = buffer;
1282   op->count_requested = count;
1283   
1284   g_simple_async_result_run_in_thread (res, write_async_thread, io_priority, cancellable);
1285   g_object_unref (res);
1286 }
1287
1288 static gssize
1289 g_output_stream_real_write_finish (GOutputStream  *stream,
1290                                    GAsyncResult   *result,
1291                                    GError        **error)
1292 {
1293   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1294   WriteData *op;
1295
1296   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_write_async);
1297   op = g_simple_async_result_get_op_res_gpointer (simple);
1298   return op->count_written;
1299 }
1300
1301 typedef struct {
1302   GInputStream *source;
1303   GOutputStreamSpliceFlags flags;
1304   gssize bytes_copied;
1305 } SpliceData;
1306
1307 static void
1308 splice_async_thread (GSimpleAsyncResult *result,
1309                      GObject            *object,
1310                      GCancellable       *cancellable)
1311 {
1312   SpliceData *op;
1313   GOutputStreamClass *class;
1314   GError *error = NULL;
1315   GOutputStream *stream;
1316
1317   stream = G_OUTPUT_STREAM (object);
1318   class = G_OUTPUT_STREAM_GET_CLASS (object);
1319   op = g_simple_async_result_get_op_res_gpointer (result);
1320   
1321   op->bytes_copied = class->splice (stream,
1322                                     op->source,
1323                                     op->flags,
1324                                     cancellable,
1325                                     &error);
1326   if (op->bytes_copied == -1)
1327     g_simple_async_result_take_error (result, error);
1328 }
1329
1330 static void
1331 g_output_stream_real_splice_async (GOutputStream             *stream,
1332                                    GInputStream              *source,
1333                                    GOutputStreamSpliceFlags   flags,
1334                                    int                        io_priority,
1335                                    GCancellable              *cancellable,
1336                                    GAsyncReadyCallback        callback,
1337                                    gpointer                   user_data)
1338 {
1339   GSimpleAsyncResult *res;
1340   SpliceData *op;
1341
1342   op = g_new0 (SpliceData, 1);
1343   res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_splice_async);
1344   g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1345   op->flags = flags;
1346   op->source = source;
1347
1348   /* TODO: In the case where both source and destintion have
1349      non-threadbased async calls we can use a true async copy here */
1350   
1351   g_simple_async_result_run_in_thread (res, splice_async_thread, io_priority, cancellable);
1352   g_object_unref (res);
1353 }
1354
1355 static gssize
1356 g_output_stream_real_splice_finish (GOutputStream  *stream,
1357                                     GAsyncResult   *result,
1358                                     GError        **error)
1359 {
1360   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1361   SpliceData *op;
1362
1363   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_splice_async);
1364   op = g_simple_async_result_get_op_res_gpointer (simple);
1365   return op->bytes_copied;
1366 }
1367
1368
1369 static void
1370 flush_async_thread (GSimpleAsyncResult *res,
1371                     GObject            *object,
1372                     GCancellable       *cancellable)
1373 {
1374   GOutputStreamClass *class;
1375   gboolean result;
1376   GError *error = NULL;
1377
1378   class = G_OUTPUT_STREAM_GET_CLASS (object);
1379   result = TRUE;
1380   if (class->flush)
1381     result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
1382
1383   if (!result)
1384     g_simple_async_result_take_error (res, error);
1385 }
1386
1387 static void
1388 g_output_stream_real_flush_async (GOutputStream       *stream,
1389                                   int                  io_priority,
1390                                   GCancellable        *cancellable,
1391                                   GAsyncReadyCallback  callback,
1392                                   gpointer             user_data)
1393 {
1394   GSimpleAsyncResult *res;
1395
1396   res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1397   
1398   g_simple_async_result_run_in_thread (res, flush_async_thread, io_priority, cancellable);
1399   g_object_unref (res);
1400 }
1401
1402 static gboolean
1403 g_output_stream_real_flush_finish (GOutputStream  *stream,
1404                                    GAsyncResult   *result,
1405                                    GError        **error)
1406 {
1407   return TRUE;
1408 }
1409
1410 static void
1411 close_async_thread (GSimpleAsyncResult *res,
1412                     GObject            *object,
1413                     GCancellable       *cancellable)
1414 {
1415   GOutputStreamClass *class;
1416   GError *error = NULL;
1417   gboolean result = TRUE;
1418
1419   class = G_OUTPUT_STREAM_GET_CLASS (object);
1420
1421   /* Do a flush here if there is a flush function, and we did not have to do
1422      an async flush before (see g_output_stream_close_async) */
1423   if (class->flush != NULL &&
1424       (class->flush_async == NULL ||
1425        class->flush_async == g_output_stream_real_flush_async))
1426     {
1427       result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
1428     }
1429
1430   /* Auto handling of cancelation disabled, and ignore
1431      cancellation, since we want to close things anyway, although
1432      possibly in a quick-n-dirty way. At least we never want to leak
1433      open handles */
1434   
1435   if (class->close_fn)
1436     {
1437       /* Make sure to close, even if the flush failed (see sync close) */
1438       if (!result)
1439         class->close_fn (G_OUTPUT_STREAM (object), cancellable, NULL);
1440       else
1441         result = class->close_fn (G_OUTPUT_STREAM (object), cancellable, &error);
1442
1443       if (!result)
1444         g_simple_async_result_take_error (res, error);
1445     }
1446 }
1447
1448 static void
1449 g_output_stream_real_close_async (GOutputStream       *stream,
1450                                   int                  io_priority,
1451                                   GCancellable        *cancellable,
1452                                   GAsyncReadyCallback  callback,
1453                                   gpointer             user_data)
1454 {
1455   GSimpleAsyncResult *res;
1456   
1457   res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_close_async);
1458
1459   g_simple_async_result_set_handle_cancellation (res, FALSE);
1460   
1461   g_simple_async_result_run_in_thread (res, close_async_thread, io_priority, cancellable);
1462   g_object_unref (res);
1463 }
1464
1465 static gboolean
1466 g_output_stream_real_close_finish (GOutputStream  *stream,
1467                                    GAsyncResult   *result,
1468                                    GError        **error)
1469 {
1470   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1471   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_close_async);
1472   return TRUE;
1473 }