Use g_simple_async_result_{new_,}take_error
[platform/upstream/glib.git] / gio / giostream.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright © 2008 codethink
4  * Copyright © 2009 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General
17  * Public License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * Authors: Ryan Lortie <desrt@desrt.ca>
22  *          Alexander Larsson <alexl@redhat.com>
23  */
24
25 #include "config.h"
26 #include <glib.h>
27 #include "glibintl.h"
28
29 #include "giostream.h"
30 #include <gio/gsimpleasyncresult.h>
31 #include <gio/gasyncresult.h>
32
33
34 G_DEFINE_ABSTRACT_TYPE (GIOStream, g_io_stream, G_TYPE_OBJECT);
35
36 /**
37  * SECTION:giostream
38  * @short_description: Base class for implementing read/write streams
39  * @include: gio/gio.h
40  * @see_also: #GInputStream, #GOutputStream
41  *
42  * GIOStream represents an object that has both read and write streams.
43  * Generally the two streams acts as separate input and output streams,
44  * but they share some common resources and state. For instance, for
45  * seekable streams they may use the same position in both streams.
46  *
47  * Examples of #GIOStream objects are #GSocketConnection which represents
48  * a two-way network connection, and #GFileIOStream which represent a
49  * file handle opened in read-write mode.
50  *
51  * To do the actual reading and writing you need to get the substreams
52  * with g_io_stream_get_input_stream() and g_io_stream_get_output_stream().
53  *
54  * The #GIOStream object owns the input and the output streams, not the other
55  * way around, so keeping the substreams alive will not keep the #GIOStream
56  * object alive. If the #GIOStream object is freed it will be closed, thus
57  * closing the substream, so even if the substreams stay alive they will
58  * always just return a %G_IO_ERROR_CLOSED for all operations.
59  *
60  * To close a stream use g_io_stream_close() which will close the common
61  * stream object and also the individual substreams. You can also close
62  * the substreams themselves. In most cases this only marks the
63  * substream as closed, so further I/O on it fails. However, some streams
64  * may support "half-closed" states where one direction of the stream
65  * is actually shut down.
66  *
67  * Since: 2.22
68  */
69
70 enum
71 {
72   PROP_0,
73   PROP_INPUT_STREAM,
74   PROP_OUTPUT_STREAM,
75   PROP_CLOSED
76 };
77
78 struct _GIOStreamPrivate {
79   guint closed : 1;
80   guint pending : 1;
81   GAsyncReadyCallback outstanding_callback;
82 };
83
84 static gboolean g_io_stream_real_close        (GIOStream            *stream,
85                                                GCancellable         *cancellable,
86                                                GError              **error);
87 static void     g_io_stream_real_close_async  (GIOStream            *stream,
88                                                int                   io_priority,
89                                                GCancellable         *cancellable,
90                                                GAsyncReadyCallback   callback,
91                                                gpointer              user_data);
92 static gboolean g_io_stream_real_close_finish (GIOStream            *stream,
93                                                GAsyncResult         *result,
94                                                GError              **error);
95
96 static void
97 g_io_stream_finalize (GObject *object)
98 {
99   G_OBJECT_CLASS (g_io_stream_parent_class)->finalize (object);
100 }
101
102 static void
103 g_io_stream_dispose (GObject *object)
104 {
105   GIOStream *stream;
106
107   stream = G_IO_STREAM (object);
108
109   if (!stream->priv->closed)
110     g_io_stream_close (stream, NULL, NULL);
111
112   G_OBJECT_CLASS (g_io_stream_parent_class)->dispose (object);
113 }
114
115 static void
116 g_io_stream_init (GIOStream *stream)
117 {
118   stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
119                                               G_TYPE_IO_STREAM,
120                                               GIOStreamPrivate);
121 }
122
123 static void
124 g_io_stream_get_property (GObject    *object,
125                           guint       prop_id,
126                           GValue     *value,
127                           GParamSpec *pspec)
128 {
129   GIOStream *stream = G_IO_STREAM (object);
130
131   switch (prop_id)
132     {
133       case PROP_CLOSED:
134         g_value_set_boolean (value, stream->priv->closed);
135         break;
136
137       case PROP_INPUT_STREAM:
138         g_value_set_object (value, g_io_stream_get_input_stream (stream));
139         break;
140
141       case PROP_OUTPUT_STREAM:
142         g_value_set_object (value, g_io_stream_get_output_stream (stream));
143         break;
144
145       default:
146         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
147     }
148 }
149
150 static void
151 g_io_stream_set_property (GObject      *object,
152                           guint         prop_id,
153                           const GValue *value,
154                           GParamSpec   *pspec)
155 {
156   switch (prop_id)
157     {
158     default:
159       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
160     }
161 }
162
163 static void
164 g_io_stream_class_init (GIOStreamClass *klass)
165 {
166   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
167
168   g_type_class_add_private (klass, sizeof (GIOStreamPrivate));
169
170   gobject_class->finalize = g_io_stream_finalize;
171   gobject_class->dispose = g_io_stream_dispose;
172   gobject_class->set_property = g_io_stream_set_property;
173   gobject_class->get_property = g_io_stream_get_property;
174
175   klass->close_fn = g_io_stream_real_close;
176   klass->close_async = g_io_stream_real_close_async;
177   klass->close_finish = g_io_stream_real_close_finish;
178
179   g_object_class_install_property (gobject_class, PROP_CLOSED,
180                                    g_param_spec_boolean ("closed",
181                                                          P_("Closed"),
182                                                          P_("Is the stream closed"),
183                                                          FALSE,
184                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
185
186   g_object_class_install_property (gobject_class, PROP_INPUT_STREAM,
187                                    g_param_spec_object ("input-stream",
188                                                         P_("Input stream"),
189                                                         P_("The GInputStream to read from"),
190                                                         G_TYPE_INPUT_STREAM,
191                                                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
192   g_object_class_install_property (gobject_class, PROP_OUTPUT_STREAM,
193                                    g_param_spec_object ("output-stream",
194                                                         P_("Output stream"),
195                                                         P_("The GOutputStream to write to"),
196                                                         G_TYPE_OUTPUT_STREAM,
197                                                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
198 }
199
200 /**
201  * g_io_stream_is_closed:
202  * @stream: a #GIOStream
203  *
204  * Checks if a stream is closed.
205  *
206  * Returns: %TRUE if the stream is closed.
207  *
208  * Since: 2.22
209  */
210 gboolean
211 g_io_stream_is_closed (GIOStream *stream)
212 {
213   g_return_val_if_fail (G_IS_IO_STREAM (stream), TRUE);
214
215   return stream->priv->closed;
216 }
217
218 /**
219  * g_io_stream_get_input_stream:
220  * @stream: a #GIOStream
221  *
222  * Gets the input stream for this object. This is used
223  * for reading.
224  *
225  * Returns: (transfer none): a #GInputStream, owned by the #GIOStream.
226  * Do not free.
227  *
228  * Since: 2.22
229  */
230 GInputStream *
231 g_io_stream_get_input_stream (GIOStream *stream)
232 {
233   GIOStreamClass *klass;
234
235   klass = G_IO_STREAM_GET_CLASS (stream);
236
237   g_assert (klass->get_input_stream != NULL);
238
239   return klass->get_input_stream (stream);
240 }
241
242 /**
243  * g_io_stream_get_output_stream:
244  * @stream: a #GIOStream
245  *
246  * Gets the output stream for this object. This is used for
247  * writing.
248  *
249  * Returns: (transfer none): a #GOutputStream, owned by the #GIOStream.
250  * Do not free.
251  *
252  * Since: 2.22
253  */
254 GOutputStream *
255 g_io_stream_get_output_stream (GIOStream *stream)
256 {
257   GIOStreamClass *klass;
258
259   klass = G_IO_STREAM_GET_CLASS (stream);
260
261   g_assert (klass->get_output_stream != NULL);
262   return klass->get_output_stream (stream);
263 }
264
265 /**
266  * g_io_stream_has_pending:
267  * @stream: a #GIOStream
268  *
269  * Checks if a stream has pending actions.
270  *
271  * Returns: %TRUE if @stream has pending actions.
272  *
273  * Since: 2.22
274  **/
275 gboolean
276 g_io_stream_has_pending (GIOStream *stream)
277 {
278   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
279
280   return stream->priv->pending;
281 }
282
283 /**
284  * g_io_stream_set_pending:
285  * @stream: a #GIOStream
286  * @error: a #GError location to store the error occuring, or %NULL to
287  *     ignore
288  *
289  * Sets @stream to have actions pending. If the pending flag is
290  * already set or @stream is closed, it will return %FALSE and set
291  * @error.
292  *
293  * Return value: %TRUE if pending was previously unset and is now set.
294  *
295  * Since: 2.22
296  */
297 gboolean
298 g_io_stream_set_pending (GIOStream  *stream,
299                          GError    **error)
300 {
301   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
302
303   if (stream->priv->closed)
304     {
305       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
306                            _("Stream is already closed"));
307       return FALSE;
308     }
309
310   if (stream->priv->pending)
311     {
312       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
313                            /* Translators: This is an error you get if there is
314                             * already an operation running against this stream when
315                             * you try to start one */
316                            _("Stream has outstanding operation"));
317       return FALSE;
318     }
319
320   stream->priv->pending = TRUE;
321   return TRUE;
322 }
323
324 /**
325  * g_io_stream_clear_pending:
326  * @stream: a #GIOStream
327  *
328  * Clears the pending flag on @stream.
329  *
330  * Since: 2.22
331  */
332 void
333 g_io_stream_clear_pending (GIOStream *stream)
334 {
335   g_return_if_fail (G_IS_IO_STREAM (stream));
336
337   stream->priv->pending = FALSE;
338 }
339
340 static gboolean
341 g_io_stream_real_close (GIOStream     *stream,
342                         GCancellable  *cancellable,
343                         GError       **error)
344 {
345   gboolean res;
346
347   res = g_output_stream_close (g_io_stream_get_output_stream (stream),
348                                cancellable, error);
349
350   /* If this errored out, unset error so that we don't report
351      further errors, but still do the following ops */
352   if (error != NULL && *error != NULL)
353     error = NULL;
354
355   res &= g_input_stream_close (g_io_stream_get_input_stream (stream),
356                                cancellable, error);
357
358   return res;
359 }
360
361 /**
362  * g_io_stream_close:
363  * @stream: a #GIOStream
364  * @cancellable: optional #GCancellable object, %NULL to ignore
365  * @error: location to store the error occuring, or %NULL to ignore
366  *
367  * Closes the stream, releasing resources related to it. This will also
368  * closes the individual input and output streams, if they are not already
369  * closed.
370  *
371  * Once the stream is closed, all other operations will return
372  * %G_IO_ERROR_CLOSED. Closing a stream multiple times will not
373  * return an error.
374  *
375  * Closing a stream will automatically flush any outstanding buffers
376  * in the stream.
377  *
378  * Streams will be automatically closed when the last reference
379  * is dropped, but you might want to call this function to make sure
380  * resources are released as early as possible.
381  *
382  * Some streams might keep the backing store of the stream (e.g. a file
383  * descriptor) open after the stream is closed. See the documentation for
384  * the individual stream for details.
385  *
386  * On failure the first error that happened will be reported, but the
387  * close operation will finish as much as possible. A stream that failed
388  * to close will still return %G_IO_ERROR_CLOSED for all operations.
389  * Still, it is important to check and report the error to the user,
390  * otherwise there might be a loss of data as all data might not be written.
391  *
392  * If @cancellable is not NULL, then the operation can be cancelled by
393  * triggering the cancellable object from another thread. If the operation
394  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
395  * Cancelling a close will still leave the stream closed, but some streams
396  * can use a faster close that doesn't block to e.g. check errors.
397  *
398  * The default implementation of this method just calls close on the
399  * individual input/output streams.
400  *
401  * Return value: %TRUE on success, %FALSE on failure
402  *
403  * Since: 2.22
404  */
405 gboolean
406 g_io_stream_close (GIOStream     *stream,
407                    GCancellable  *cancellable,
408                    GError       **error)
409 {
410   GIOStreamClass *class;
411   gboolean res;
412
413   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
414
415   class = G_IO_STREAM_GET_CLASS (stream);
416
417   if (stream->priv->closed)
418     return TRUE;
419
420   if (!g_io_stream_set_pending (stream, error))
421     return FALSE;
422
423   if (cancellable)
424     g_cancellable_push_current (cancellable);
425
426   res = TRUE;
427   if (class->close_fn)
428     res = class->close_fn (stream, cancellable, error);
429
430   if (cancellable)
431     g_cancellable_pop_current (cancellable);
432
433   stream->priv->closed = TRUE;
434   g_io_stream_clear_pending (stream);
435
436   return res;
437 }
438
439 static void
440 async_ready_close_callback_wrapper (GObject      *source_object,
441                                     GAsyncResult *res,
442                                     gpointer      user_data)
443 {
444   GIOStream *stream = G_IO_STREAM (source_object);
445
446   stream->priv->closed = TRUE;
447   g_io_stream_clear_pending (stream);
448   if (stream->priv->outstanding_callback)
449     (*stream->priv->outstanding_callback) (source_object, res, user_data);
450   g_object_unref (stream);
451 }
452
453 /**
454  * g_io_stream_close_async:
455  * @stream: a #GIOStream
456  * @io_priority: the io priority of the request
457  * @callback: callback to call when the request is satisfied
458  * @user_data: the data to pass to callback function
459  * @cancellable: optional cancellable object
460  *
461  * Requests an asynchronous close of the stream, releasing resources
462  * related to it. When the operation is finished @callback will be
463  * called. You can then call g_io_stream_close_finish() to get
464  * the result of the operation.
465  *
466  * For behaviour details see g_io_stream_close().
467  *
468  * The asynchronous methods have a default fallback that uses threads
469  * to implement asynchronicity, so they are optional for inheriting
470  * classes. However, if you override one you must override all.
471  *
472  * Since: 2.22
473  */
474 void
475 g_io_stream_close_async (GIOStream           *stream,
476                          int                  io_priority,
477                          GCancellable        *cancellable,
478                          GAsyncReadyCallback  callback,
479                          gpointer             user_data)
480 {
481   GIOStreamClass *class;
482   GSimpleAsyncResult *simple;
483   GError *error = NULL;
484
485   g_return_if_fail (G_IS_IO_STREAM (stream));
486
487   if (stream->priv->closed)
488     {
489       simple = g_simple_async_result_new (G_OBJECT (stream),
490                                           callback,
491                                           user_data,
492                                           g_io_stream_close_async);
493       g_simple_async_result_complete_in_idle (simple);
494       g_object_unref (simple);
495       return;
496     }
497
498   if (!g_io_stream_set_pending (stream, &error))
499     {
500       g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
501                                             callback,
502                                             user_data,
503                                             error);
504       g_error_free (error);
505       return;
506     }
507
508   class = G_IO_STREAM_GET_CLASS (stream);
509   stream->priv->outstanding_callback = callback;
510   g_object_ref (stream);
511   class->close_async (stream, io_priority, cancellable,
512                       async_ready_close_callback_wrapper, user_data);
513 }
514
515 /**
516  * g_io_stream_close_finish:
517  * @stream: a #GIOStream
518  * @result: a #GAsyncResult
519  * @error: a #GError location to store the error occuring, or %NULL to
520  *    ignore
521  *
522  * Closes a stream.
523  *
524  * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
525  *
526  * Since: 2.22
527  */
528 gboolean
529 g_io_stream_close_finish (GIOStream     *stream,
530                           GAsyncResult  *result,
531                           GError       **error)
532 {
533   GSimpleAsyncResult *simple;
534   GIOStreamClass *class;
535
536   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
537   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
538
539   if (G_IS_SIMPLE_ASYNC_RESULT (result))
540     {
541       simple = G_SIMPLE_ASYNC_RESULT (result);
542       if (g_simple_async_result_propagate_error (simple, error))
543         return FALSE;
544
545       /* Special case already closed */
546       if (g_simple_async_result_get_source_tag (simple) == g_io_stream_close_async)
547         return TRUE;
548     }
549
550   class = G_IO_STREAM_GET_CLASS (stream);
551   return class->close_finish (stream, result, error);
552 }
553
554
555 static void
556 close_async_thread (GSimpleAsyncResult *res,
557                     GObject            *object,
558                     GCancellable       *cancellable)
559 {
560   GIOStreamClass *class;
561   GError *error = NULL;
562   gboolean result;
563
564   /* Auto handling of cancelation disabled, and ignore cancellation,
565    * since we want to close things anyway, although possibly in a
566    * quick-n-dirty way. At least we never want to leak open handles
567    */
568   class = G_IO_STREAM_GET_CLASS (object);
569   if (class->close_fn)
570     {
571       result = class->close_fn (G_IO_STREAM (object), cancellable, &error);
572       if (!result)
573         g_simple_async_result_take_error (res, error);
574     }
575 }
576
577 static void
578 g_io_stream_real_close_async (GIOStream           *stream,
579                               int                  io_priority,
580                               GCancellable        *cancellable,
581                               GAsyncReadyCallback  callback,
582                               gpointer             user_data)
583 {
584   GSimpleAsyncResult *res;
585
586   res = g_simple_async_result_new (G_OBJECT (stream),
587                                    callback,
588                                    user_data,
589                                    g_io_stream_real_close_async);
590
591   g_simple_async_result_set_handle_cancellation (res, FALSE);
592
593   g_simple_async_result_run_in_thread (res,
594                                        close_async_thread,
595                                        io_priority,
596                                        cancellable);
597   g_object_unref (res);
598 }
599
600 static gboolean
601 g_io_stream_real_close_finish (GIOStream     *stream,
602                                GAsyncResult  *result,
603                                GError       **error)
604 {
605   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
606   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) ==
607                   g_io_stream_real_close_async);
608   return TRUE;
609 }