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