6f3de48faa929b8ccf8ea28fc25be628d9e9ffd1
[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 #include "gioalias.h"
34
35 G_DEFINE_TYPE (GIOStream, g_io_stream, G_TYPE_OBJECT);
36
37 /**
38  * SECTION:ginputstream
39  * @short_description: Base class for implementing readwrite streams
40  * @include: gio/gio.h
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  * To do the actual reading and writing you need to get the substreams
48  * with g_io_stream_get_input_stream() and g_io_stream_get_output_stream().
49  *
50  * The #GIOStream object owns the input and the output streams, not the other
51  * way around, so keeping the substreams alive will not keep the #GIOStream
52  * object alive. If the #GIOStream object is freed it will be closed, thus
53  * closing the substream, so even if the substreams stay alive they will
54  * always just return a %G_IO_ERROR_CLOSED for all operations.
55  *
56  * To close a stream use g_io_stream_close() which will close the common
57  * stream object and also the individual substreams. You can also close
58  * the substreams themselves. In most cases this only marks the
59  * substream as closed, so further I/O on it fails. However, some streams
60  * may support "half-closed" states where one direction of the stream
61  * is actually shut down.
62  *
63  * Since: 2.22
64  **/
65
66 enum
67 {
68   PROP_0,
69   PROP_INPUT_STREAM,
70   PROP_OUTPUT_STREAM,
71   PROP_CLOSED
72 };
73
74 struct _GIOStreamPrivate {
75   guint closed : 1;
76   guint pending : 1;
77   GAsyncReadyCallback outstanding_callback;
78 };
79
80 static gboolean g_io_stream_real_close        (GIOStream            *stream,
81                                                GCancellable         *cancellable,
82                                                GError              **error);
83 static void     g_io_stream_real_close_async  (GIOStream            *stream,
84                                                int                   io_priority,
85                                                GCancellable         *cancellable,
86                                                GAsyncReadyCallback   callback,
87                                                gpointer              user_data);
88 static gboolean g_io_stream_real_close_finish (GIOStream            *stream,
89                                                GAsyncResult         *result,
90                                                GError              **error);
91
92 static void
93 g_io_stream_finalize (GObject *object)
94 {
95   GIOStream *stream;
96
97   stream = G_IO_STREAM (object);
98
99   if (!stream->priv->closed)
100     g_io_stream_close (stream, NULL, NULL);
101
102   G_OBJECT_CLASS (g_io_stream_parent_class)->finalize (object);
103 }
104
105 static void
106 g_io_stream_dispose (GObject *object)
107 {
108   GIOStream *stream;
109
110   stream = G_IO_STREAM (object);
111
112   if (!stream->priv->closed)
113     g_io_stream_close (stream, NULL, NULL);
114
115   G_OBJECT_CLASS (g_io_stream_parent_class)->dispose (object);
116 }
117
118 static void
119 g_io_stream_init (GIOStream *stream)
120 {
121   stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
122                                               G_TYPE_IO_STREAM,
123                                               GIOStreamPrivate);
124 }
125
126 static void
127 g_io_stream_get_property (GObject    *object,
128                           guint       prop_id,
129                           GValue     *value,
130                           GParamSpec *pspec)
131 {
132   GIOStream *stream = G_IO_STREAM (object);
133
134   switch (prop_id)
135     {
136       case PROP_CLOSED:
137         g_value_set_boolean (value, stream->priv->closed);
138         break;
139
140       case PROP_INPUT_STREAM:
141         g_value_set_object (value, g_io_stream_get_input_stream (stream));
142         break;
143
144       case PROP_OUTPUT_STREAM:
145         g_value_set_object (value, g_io_stream_get_output_stream (stream));
146         break;
147
148       default:
149         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
150     }
151 }
152
153 static void
154 g_io_stream_set_property (GObject      *object,
155                           guint         prop_id,
156                           const GValue *value,
157                           GParamSpec   *pspec)
158 {
159   switch (prop_id)
160     {
161     default:
162       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
163     }
164 }
165
166 static void
167 g_io_stream_class_init (GIOStreamClass *klass)
168 {
169   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
170
171   g_type_class_add_private (klass, sizeof (GIOStreamPrivate));
172
173   gobject_class->finalize = g_io_stream_finalize;
174   gobject_class->dispose = g_io_stream_dispose;
175   gobject_class->set_property = g_io_stream_set_property;
176   gobject_class->get_property = g_io_stream_get_property;
177
178   klass->close_fn = g_io_stream_real_close;
179   klass->close_async = g_io_stream_real_close_async;
180   klass->close_finish = g_io_stream_real_close_finish;
181
182   g_object_class_install_property (gobject_class, PROP_CLOSED,
183                                    g_param_spec_boolean ("closed",
184                                                          P_("Closed"),
185                                                          P_("Is the stream closed"),
186                                                          FALSE,
187                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
188
189   g_object_class_install_property (gobject_class, PROP_INPUT_STREAM,
190                                    g_param_spec_object ("input-stream",
191                                                         P_("Input stream"),
192                                                         P_("The GInputStream to read from"),
193                                                         G_TYPE_INPUT_STREAM,
194                                                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
195   g_object_class_install_property (gobject_class, PROP_OUTPUT_STREAM,
196                                    g_param_spec_object ("output-stream",
197                                                         P_("Output stream"),
198                                                         P_("The GOutputStream to write to"),
199                                                         G_TYPE_OUTPUT_STREAM,
200                                                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
201 }
202
203 /**
204  * g_io_stream_is_closed:
205  * @stream: a #GIOStream.
206  *
207  * Checks if a stream is closed.
208  *
209  * Returns: %TRUE if the stream is closed.
210  *
211  * Since: 2.22
212  **/
213 gboolean
214 g_io_stream_is_closed (GIOStream *stream)
215 {
216   g_return_val_if_fail (G_IS_IO_STREAM (stream), TRUE);
217
218   return stream->priv->closed;
219 }
220
221 /**
222  * g_io_stream_get_input_stream:
223  * @stream: input #GIOStream.
224  *
225  * Gets the input stream for this object. This is used
226  * for reading.
227  *
228  * Returns: a #GInputStream, owned by the #GIOStream do not free.
229  *
230  * Since: 2.22
231  **/
232 GInputStream *
233 g_io_stream_get_input_stream (GIOStream *io_stream)
234 {
235   GIOStreamClass *klass;
236
237   klass = G_IO_STREAM_GET_CLASS (io_stream);
238
239   g_assert (klass->get_input_stream != NULL);
240
241   return klass->get_input_stream (io_stream);
242 }
243
244 /**
245  * g_io_stream_get_output_stream:
246  * @stream: input #GIOStream.
247  *
248  * Gets the output stream for this object. This is used for
249  * writing.
250  *
251  * Returns: a #GOutputStream, owned by the #GIOStream do not free.
252  *
253  * Since: 2.22
254  **/
255 GOutputStream *
256 g_io_stream_get_output_stream (GIOStream *io_stream)
257 {
258   GIOStreamClass *klass;
259
260   klass = G_IO_STREAM_GET_CLASS (io_stream);
261
262   g_assert (klass->get_output_stream != NULL);
263   return klass->get_output_stream (io_stream);
264 }
265
266 /**
267  * g_io_stream_has_pending:
268  * @stream: a #GIOStream.
269  *
270  * Checks if a stream has pending actions.
271  *
272  * Returns: %TRUE if @stream has pending actions. 
273  *
274  * Since: 2.22
275  **/
276 gboolean
277 g_io_stream_has_pending (GIOStream *stream)
278 {
279   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
280
281   return stream->priv->pending;
282 }
283
284 /**
285  * g_io_stream_set_pending:
286  * @stream: a #GIOStream.
287  * @error: a #GError location to store the error occuring, or %NULL to 
288  * ignore.
289  *
290  * Sets @stream to have actions pending. If the pending flag is
291  * already set or @stream is closed, it will return %FALSE and set
292  * @error.
293  *
294  * Return value: %TRUE if pending was previously unset and is now set.
295  *
296  * Since: 2.22
297  **/
298 gboolean
299 g_io_stream_set_pending (GIOStream *stream,
300                          GError **error)
301 {
302   g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE);
303
304   if (stream->priv->closed)
305     {
306       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
307                            _("Stream is already closed"));
308       return FALSE;
309     }
310
311   if (stream->priv->pending)
312     {
313       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
314                            /* Translators: This is an error you get if there is
315                             * already an operation running against this stream when
316                             * you try to start one */
317                            _("Stream has outstanding operation"));
318       return FALSE;
319     }
320
321   stream->priv->pending = TRUE;
322   return TRUE;
323 }
324
325 /**
326  * g_io_stream_clear_pending:
327  * @stream: output stream
328  *
329  * Clears the pending flag on @stream.
330  *
331  * Since: 2.22
332  **/
333 void
334 g_io_stream_clear_pending (GIOStream *stream)
335 {
336   g_return_if_fail (G_IS_IO_STREAM (stream));
337
338   stream->priv->pending = FALSE;
339 }
340
341 static gboolean
342 g_io_stream_real_close (GIOStream            *stream,
343                         GCancellable         *cancellable,
344                         GError              **error)
345 {
346   gboolean res;
347
348   res = g_output_stream_close (g_io_stream_get_output_stream (stream),
349                                cancellable, error);
350
351   /* If this errored out, unset error so that we don't report
352      further errors, but still do the following ops */
353   if (error != NULL && *error != NULL)
354     error = NULL;
355
356   res &= g_input_stream_close (g_io_stream_get_input_stream (stream),
357                                cancellable, error);
358
359   return res;
360 }
361
362 /**
363  * g_io_stream_close:
364  * @stream: A #GIOStream.
365  * @cancellable: optional #GCancellable object, %NULL to ignore.
366  * @error: location to store the error occuring, or %NULL to ignore
367  *
368  * Closes the stream, releasing resources related to it. This will also
369  * closes the individual input and output streams, if they are not already
370  * closed.
371  *
372  * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
373  * Closing a stream multiple times will not return an error.
374  *
375  * Closing a stream will automatically flush any outstanding buffers in the
376  * 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 descriptor)
383  * open after the stream is closed. See the documentation for the individual
384  * stream for details.
385  *
386  * On failure the first error that happened will be reported, but the close
387  * operation will finish as much as possible. A stream that failed to
388  * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it
389  * is important to check and report the error to the user, otherwise
390  * 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 asyncronous 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
565      cancellation, since we want to close things anyway, although
566      possibly in a quick-n-dirty way. At least we never want to leak
567      open handles */
568
569   class = G_IO_STREAM_GET_CLASS (object);
570   result = class->close_fn (G_IO_STREAM (object), cancellable, &error);
571   if (!result)
572     {
573       g_simple_async_result_set_from_error (res, error);
574       g_error_free (error);
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 }
611
612 #define __G_IO_STREAM_C__
613 #include "gioaliasdef.c"