gio/: fully remove gioalias hacks
[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_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: a #GInputStream, owned by the #GIOStream. Do not free.
226  *
227  * Since: 2.22
228  */
229 GInputStream *
230 g_io_stream_get_input_stream (GIOStream *stream)
231 {
232   GIOStreamClass *klass;
233
234   klass = G_IO_STREAM_GET_CLASS (stream);
235
236   g_assert (klass->get_input_stream != NULL);
237
238   return klass->get_input_stream (stream);
239 }
240
241 /**
242  * g_io_stream_get_output_stream:
243  * @stream: a #GIOStream
244  *
245  * Gets the output stream for this object. This is used for
246  * writing.
247  *
248  * Returns: a #GOutputStream, owned by the #GIOStream. Do not free.
249  *
250  * Since: 2.22
251  */
252 GOutputStream *
253 g_io_stream_get_output_stream (GIOStream *stream)
254 {
255   GIOStreamClass *klass;
256
257   klass = G_IO_STREAM_GET_CLASS (stream);
258
259   g_assert (klass->get_output_stream != NULL);
260   return klass->get_output_stream (stream);
261 }
262
263 /**
264  * g_io_stream_has_pending:
265  * @stream: a #GIOStream
266  *
267  * Checks if a stream has pending actions.
268  *
269  * Returns: %TRUE if @stream has pending actions.
270  *
271  * Since: 2.22
272  **/
273 gboolean
274 g_io_stream_has_pending (GIOStream *stream)
275 {
276   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
277
278   return stream->priv->pending;
279 }
280
281 /**
282  * g_io_stream_set_pending:
283  * @stream: a #GIOStream
284  * @error: a #GError location to store the error occuring, or %NULL to
285  *     ignore
286  *
287  * Sets @stream to have actions pending. If the pending flag is
288  * already set or @stream is closed, it will return %FALSE and set
289  * @error.
290  *
291  * Return value: %TRUE if pending was previously unset and is now set.
292  *
293  * Since: 2.22
294  */
295 gboolean
296 g_io_stream_set_pending (GIOStream  *stream,
297                          GError    **error)
298 {
299   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
300
301   if (stream->priv->closed)
302     {
303       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
304                            _("Stream is already closed"));
305       return FALSE;
306     }
307
308   if (stream->priv->pending)
309     {
310       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
311                            /* Translators: This is an error you get if there is
312                             * already an operation running against this stream when
313                             * you try to start one */
314                            _("Stream has outstanding operation"));
315       return FALSE;
316     }
317
318   stream->priv->pending = TRUE;
319   return TRUE;
320 }
321
322 /**
323  * g_io_stream_clear_pending:
324  * @stream: a #GIOStream
325  *
326  * Clears the pending flag on @stream.
327  *
328  * Since: 2.22
329  */
330 void
331 g_io_stream_clear_pending (GIOStream *stream)
332 {
333   g_return_if_fail (G_IS_IO_STREAM (stream));
334
335   stream->priv->pending = FALSE;
336 }
337
338 static gboolean
339 g_io_stream_real_close (GIOStream     *stream,
340                         GCancellable  *cancellable,
341                         GError       **error)
342 {
343   gboolean res;
344
345   res = g_output_stream_close (g_io_stream_get_output_stream (stream),
346                                cancellable, error);
347
348   /* If this errored out, unset error so that we don't report
349      further errors, but still do the following ops */
350   if (error != NULL && *error != NULL)
351     error = NULL;
352
353   res &= g_input_stream_close (g_io_stream_get_input_stream (stream),
354                                cancellable, error);
355
356   return res;
357 }
358
359 /**
360  * g_io_stream_close:
361  * @stream: a #GIOStream
362  * @cancellable: optional #GCancellable object, %NULL to ignore
363  * @error: location to store the error occuring, or %NULL to ignore
364  *
365  * Closes the stream, releasing resources related to it. This will also
366  * closes the individual input and output streams, if they are not already
367  * closed.
368  *
369  * Once the stream is closed, all other operations will return
370  * %G_IO_ERROR_CLOSED. Closing a stream multiple times will not
371  * return an error.
372  *
373  * Closing a stream will automatically flush any outstanding buffers
374  * in the stream.
375  *
376  * Streams will be automatically closed when the last reference
377  * is dropped, but you might want to call this function to make sure
378  * resources are released as early as possible.
379  *
380  * Some streams might keep the backing store of the stream (e.g. a file
381  * descriptor) open after the stream is closed. See the documentation for
382  * the individual stream for details.
383  *
384  * On failure the first error that happened will be reported, but the
385  * close operation will finish as much as possible. A stream that failed
386  * to close will still return %G_IO_ERROR_CLOSED for all operations.
387  * Still, it is important to check and report the error to the user,
388  * otherwise there might be a loss of data as all data might not be written.
389  *
390  * If @cancellable is not NULL, then the operation can be cancelled by
391  * triggering the cancellable object from another thread. If the operation
392  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
393  * Cancelling a close will still leave the stream closed, but some streams
394  * can use a faster close that doesn't block to e.g. check errors.
395  *
396  * The default implementation of this method just calls close on the
397  * individual input/output streams.
398  *
399  * Return value: %TRUE on success, %FALSE on failure
400  *
401  * Since: 2.22
402  */
403 gboolean
404 g_io_stream_close (GIOStream     *stream,
405                    GCancellable  *cancellable,
406                    GError       **error)
407 {
408   GIOStreamClass *class;
409   gboolean res;
410
411   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
412
413   class = G_IO_STREAM_GET_CLASS (stream);
414
415   if (stream->priv->closed)
416     return TRUE;
417
418   if (!g_io_stream_set_pending (stream, error))
419     return FALSE;
420
421   if (cancellable)
422     g_cancellable_push_current (cancellable);
423
424   res = TRUE;
425   if (class->close_fn)
426     res = class->close_fn (stream, cancellable, error);
427
428   if (cancellable)
429     g_cancellable_pop_current (cancellable);
430
431   stream->priv->closed = TRUE;
432   g_io_stream_clear_pending (stream);
433
434   return res;
435 }
436
437 static void
438 async_ready_close_callback_wrapper (GObject      *source_object,
439                                     GAsyncResult *res,
440                                     gpointer      user_data)
441 {
442   GIOStream *stream = G_IO_STREAM (source_object);
443
444   stream->priv->closed = TRUE;
445   g_io_stream_clear_pending (stream);
446   if (stream->priv->outstanding_callback)
447     (*stream->priv->outstanding_callback) (source_object, res, user_data);
448   g_object_unref (stream);
449 }
450
451 /**
452  * g_io_stream_close_async:
453  * @stream: a #GIOStream
454  * @io_priority: the io priority of the request
455  * @callback: callback to call when the request is satisfied
456  * @user_data: the data to pass to callback function
457  * @cancellable: optional cancellable object
458  *
459  * Requests an asynchronous close of the stream, releasing resources
460  * related to it. When the operation is finished @callback will be
461  * called. You can then call g_io_stream_close_finish() to get
462  * the result of the operation.
463  *
464  * For behaviour details see g_io_stream_close().
465  *
466  * The asynchronous methods have a default fallback that uses threads
467  * to implement asynchronicity, so they are optional for inheriting
468  * classes. However, if you override one you must override all.
469  *
470  * Since: 2.22
471  */
472 void
473 g_io_stream_close_async (GIOStream           *stream,
474                          int                  io_priority,
475                          GCancellable        *cancellable,
476                          GAsyncReadyCallback  callback,
477                          gpointer             user_data)
478 {
479   GIOStreamClass *class;
480   GSimpleAsyncResult *simple;
481   GError *error = NULL;
482
483   g_return_if_fail (G_IS_IO_STREAM (stream));
484
485   if (stream->priv->closed)
486     {
487       simple = g_simple_async_result_new (G_OBJECT (stream),
488                                           callback,
489                                           user_data,
490                                           g_io_stream_close_async);
491       g_simple_async_result_complete_in_idle (simple);
492       g_object_unref (simple);
493       return;
494     }
495
496   if (!g_io_stream_set_pending (stream, &error))
497     {
498       g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
499                                             callback,
500                                             user_data,
501                                             error);
502       g_error_free (error);
503       return;
504     }
505
506   class = G_IO_STREAM_GET_CLASS (stream);
507   stream->priv->outstanding_callback = callback;
508   g_object_ref (stream);
509   class->close_async (stream, io_priority, cancellable,
510                       async_ready_close_callback_wrapper, user_data);
511 }
512
513 /**
514  * g_io_stream_close_finish:
515  * @stream: a #GIOStream
516  * @result: a #GAsyncResult
517  * @error: a #GError location to store the error occuring, or %NULL to
518  *    ignore
519  *
520  * Closes a stream.
521  *
522  * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
523  *
524  * Since: 2.22
525  */
526 gboolean
527 g_io_stream_close_finish (GIOStream     *stream,
528                           GAsyncResult  *result,
529                           GError       **error)
530 {
531   GSimpleAsyncResult *simple;
532   GIOStreamClass *class;
533
534   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
535   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
536
537   if (G_IS_SIMPLE_ASYNC_RESULT (result))
538     {
539       simple = G_SIMPLE_ASYNC_RESULT (result);
540       if (g_simple_async_result_propagate_error (simple, error))
541         return FALSE;
542
543       /* Special case already closed */
544       if (g_simple_async_result_get_source_tag (simple) == g_io_stream_close_async)
545         return TRUE;
546     }
547
548   class = G_IO_STREAM_GET_CLASS (stream);
549   return class->close_finish (stream, result, error);
550 }
551
552
553 static void
554 close_async_thread (GSimpleAsyncResult *res,
555                     GObject            *object,
556                     GCancellable       *cancellable)
557 {
558   GIOStreamClass *class;
559   GError *error = NULL;
560   gboolean result;
561
562   /* Auto handling of cancelation disabled, and ignore cancellation,
563    * since we want to close things anyway, although possibly in a
564    * quick-n-dirty way. At least we never want to leak open handles
565    */
566   class = G_IO_STREAM_GET_CLASS (object);
567   if (class->close_fn)
568     {
569       result = class->close_fn (G_IO_STREAM (object), cancellable, &error);
570       if (!result)
571         {
572           g_simple_async_result_set_from_error (res, error);
573           g_error_free (error);
574         }
575     }
576 }
577
578 static void
579 g_io_stream_real_close_async (GIOStream           *stream,
580                               int                  io_priority,
581                               GCancellable        *cancellable,
582                               GAsyncReadyCallback  callback,
583                               gpointer             user_data)
584 {
585   GSimpleAsyncResult *res;
586
587   res = g_simple_async_result_new (G_OBJECT (stream),
588                                    callback,
589                                    user_data,
590                                    g_io_stream_real_close_async);
591
592   g_simple_async_result_set_handle_cancellation (res, FALSE);
593
594   g_simple_async_result_run_in_thread (res,
595                                        close_async_thread,
596                                        io_priority,
597                                        cancellable);
598   g_object_unref (res);
599 }
600
601 static gboolean
602 g_io_stream_real_close_finish (GIOStream     *stream,
603                                GAsyncResult  *result,
604                                GError       **error)
605 {
606   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
607   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) ==
608                   g_io_stream_real_close_async);
609   return TRUE;
610 }