Add g_type_ensure() and use it rather than playing games with volatile
[platform/upstream/glib.git] / gio / gsocketconnection.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
4  *           © 2008 codethink
5  * Copyright © 2009 Red Hat, Inc
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * Authors: Christian Kellner <gicmo@gnome.org>
23  *          Samuel Cormier-Iijima <sciyoshi@gmail.com>
24  *          Ryan Lortie <desrt@desrt.ca>
25  *          Alexander Larsson <alexl@redhat.com>
26  */
27
28 #include "config.h"
29
30 #include "gsocketconnection.h"
31
32 #include "gsocketoutputstream.h"
33 #include "gsocketinputstream.h"
34 #include <gio/giostream.h>
35 #include <gio/gsimpleasyncresult.h>
36 #include "gunixconnection.h"
37 #include "gtcpconnection.h"
38 #include "glibintl.h"
39
40
41 /**
42  * SECTION:gsocketconnection
43  * @short_description: A socket connection
44  * @include: gio/gio.h
45  * @see_also: #GIOStream, #GSocketClient, #GSocketListener
46  *
47  * #GSocketConnection is a #GIOStream for a connected socket. They
48  * can be created either by #GSocketClient when connecting to a host,
49  * or by #GSocketListener when accepting a new client.
50  *
51  * The type of the #GSocketConnection object returned from these calls
52  * depends on the type of the underlying socket that is in use. For
53  * instance, for a TCP/IP connection it will be a #GTcpConnection.
54  *
55  * Choosing what type of object to construct is done with the socket
56  * connection factory, and it is possible for 3rd parties to register
57  * custom socket connection types for specific combination of socket
58  * family/type/protocol using g_socket_connection_factory_register_type().
59  *
60  * Since: 2.22
61  */
62
63 G_DEFINE_TYPE (GSocketConnection, g_socket_connection, G_TYPE_IO_STREAM);
64
65 enum
66 {
67   PROP_NONE,
68   PROP_SOCKET,
69 };
70
71 struct _GSocketConnectionPrivate
72 {
73   GSocket       *socket;
74   GInputStream  *input_stream;
75   GOutputStream *output_stream;
76
77   gboolean       in_dispose;
78 };
79
80 static gboolean g_socket_connection_close         (GIOStream            *stream,
81                                                    GCancellable         *cancellable,
82                                                    GError              **error);
83 static void     g_socket_connection_close_async   (GIOStream            *stream,
84                                                    int                   io_priority,
85                                                    GCancellable         *cancellable,
86                                                    GAsyncReadyCallback   callback,
87                                                    gpointer              user_data);
88 static gboolean g_socket_connection_close_finish  (GIOStream            *stream,
89                                                    GAsyncResult         *result,
90                                                    GError              **error);
91
92 static GInputStream *
93 g_socket_connection_get_input_stream (GIOStream *io_stream)
94 {
95   GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
96
97   if (connection->priv->input_stream == NULL)
98     connection->priv->input_stream = (GInputStream *)
99       _g_socket_input_stream_new (connection->priv->socket);
100
101   return connection->priv->input_stream;
102 }
103
104 static GOutputStream *
105 g_socket_connection_get_output_stream (GIOStream *io_stream)
106 {
107   GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
108
109   if (connection->priv->output_stream == NULL)
110     connection->priv->output_stream = (GOutputStream *)
111       _g_socket_output_stream_new (connection->priv->socket);
112
113   return connection->priv->output_stream;
114 }
115
116 /**
117  * g_socket_connection_is_connected:
118  * @connection: a #GSocketConnection
119  *
120  * Checks if @connection is connected. This is equivalent to calling
121  * g_socket_is_connected() on @connection's underlying #GSocket.
122  *
123  * Returns: whether @connection is connected
124  *
125  * Since: 2.32
126  */
127 gboolean
128 g_socket_connection_is_connected (GSocketConnection  *connection)
129 {
130   return g_socket_is_connected (connection->priv->socket);
131 }
132
133 /**
134  * g_socket_connection_connect:
135  * @connection: a #GSocketConnection
136  * @address: a #GSocketAddress specifying the remote address.
137  * @cancellable: (allow-none): a %GCancellable or %NULL
138  * @error: #GError for error reporting, or %NULL to ignore.
139  *
140  * Connect @connection to the specified remote address.
141  *
142  * Returns: %TRUE if the connection succeeded, %FALSE on error
143  *
144  * Since: 2.32
145  */
146 gboolean
147 g_socket_connection_connect (GSocketConnection  *connection,
148                              GSocketAddress     *address,
149                              GCancellable       *cancellable,
150                              GError            **error)
151 {
152   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
153   g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE);
154
155   return g_socket_connect (connection->priv->socket, address,
156                            cancellable, error);
157 }
158
159 static gboolean g_socket_connection_connect_callback (GSocket      *socket,
160                                                       GIOCondition  condition,
161                                                       gpointer      user_data);
162
163 /**
164  * g_socket_connection_connect_async:
165  * @connection: a #GSocketConnection
166  * @address: a #GSocketAddress specifying the remote address.
167  * @cancellable: (allow-none): a %GCancellable or %NULL
168  * @callback: (scope async): a #GAsyncReadyCallback
169  * @user_data: (closure): user data for the callback
170  *
171  * Asynchronously connect @connection to the specified remote address.
172  *
173  * This clears the #GSocket:blocking flag on @connection's underlying
174  * socket if it is currently set.
175  *
176  * Use g_socket_connection_connect_finish() to retrieve the result.
177  *
178  * Since: 2.32
179  */
180 void
181 g_socket_connection_connect_async (GSocketConnection   *connection,
182                                    GSocketAddress      *address,
183                                    GCancellable        *cancellable,
184                                    GAsyncReadyCallback  callback,
185                                    gpointer             user_data)
186 {
187   GSimpleAsyncResult *simple;
188   GError *tmp_error = NULL;
189
190   g_return_if_fail (G_IS_SOCKET_CONNECTION (connection));
191   g_return_if_fail (G_IS_SOCKET_ADDRESS (address));
192
193   simple = g_simple_async_result_new (G_OBJECT (connection),
194                                       callback, user_data,
195                                       g_socket_connection_connect_async);
196
197   g_socket_set_blocking (connection->priv->socket, FALSE);
198
199   if (g_socket_connect (connection->priv->socket, address,
200                         cancellable, &tmp_error))
201     {
202       g_simple_async_result_set_op_res_gboolean (simple, TRUE);
203       g_simple_async_result_complete_in_idle (simple);
204     }
205   else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
206     {
207       GSource *source;
208
209       g_error_free (tmp_error);
210       source = g_socket_create_source (connection->priv->socket,
211                                        G_IO_OUT, cancellable);
212       g_source_set_callback (source,
213                              (GSourceFunc) g_socket_connection_connect_callback,
214                              simple, NULL);
215       g_source_attach (source, g_main_context_get_thread_default ());
216       g_source_unref (source);
217     }
218   else
219     {
220       g_simple_async_result_take_error (simple, tmp_error);
221       g_simple_async_result_complete_in_idle (simple);
222     }
223 }
224
225 static gboolean
226 g_socket_connection_connect_callback (GSocket      *socket,
227                                       GIOCondition  condition,
228                                       gpointer      user_data)
229 {
230   GSimpleAsyncResult *simple = user_data;
231   GSocketConnection *connection;
232   GError *error = NULL;
233
234   connection = G_SOCKET_CONNECTION (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
235   g_object_unref (connection);
236
237   if (g_socket_check_connect_result (connection->priv->socket, &error))
238     g_simple_async_result_set_op_res_gboolean (simple, TRUE);
239   else
240     g_simple_async_result_take_error (simple, error);
241
242   g_simple_async_result_complete (simple);
243   g_object_unref (simple);
244   return FALSE;
245 }
246
247 /**
248  * g_socket_connection_connect_finish:
249  * @connection: a #GSocketConnection
250  * @result: the #GAsyncResult
251  * @error: #GError for error reporting, or %NULL to ignore.
252  *
253  * Gets the result of a g_socket_connection_connect_async() call.
254  *
255  * Returns: %TRUE if the connection succeeded, %FALSE on error
256  *
257  * Since: 2.32
258  */
259 gboolean
260 g_socket_connection_connect_finish (GSocketConnection  *connection,
261                                     GAsyncResult       *result,
262                                     GError            **error)
263 {
264   GSimpleAsyncResult *simple;
265
266   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
267   g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), g_socket_connection_connect_async), FALSE);
268
269   simple = G_SIMPLE_ASYNC_RESULT (result);
270   if (g_simple_async_result_propagate_error (simple, error))
271     return FALSE;
272   return TRUE;
273 }
274
275 /**
276  * g_socket_connection_get_socket:
277  * @connection: a #GSocketConnection
278  *
279  * Gets the underlying #GSocket object of the connection.
280  * This can be useful if you want to do something unusual on it
281  * not supported by the #GSocketConnection APIs.
282  *
283  * Returns: (transfer none): a #GSocketAddress or %NULL on error.
284  *
285  * Since: 2.22
286  */
287 GSocket *
288 g_socket_connection_get_socket (GSocketConnection *connection)
289 {
290   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), NULL);
291
292   return connection->priv->socket;
293 }
294
295 /**
296  * g_socket_connection_get_local_address:
297  * @connection: a #GSocketConnection
298  * @error: #GError for error reporting, or %NULL to ignore.
299  *
300  * Try to get the local address of a socket connection.
301  *
302  * Returns: (transfer full): a #GSocketAddress or %NULL on error.
303  *     Free the returned object with g_object_unref().
304  *
305  * Since: 2.22
306  */
307 GSocketAddress *
308 g_socket_connection_get_local_address (GSocketConnection  *connection,
309                                        GError            **error)
310 {
311   return g_socket_get_local_address (connection->priv->socket, error);
312 }
313
314 /**
315  * g_socket_connection_get_remote_address:
316  * @connection: a #GSocketConnection
317  * @error: #GError for error reporting, or %NULL to ignore.
318  *
319  * Try to get the remote address of a socket connection.
320  *
321  * Returns: (transfer full): a #GSocketAddress or %NULL on error.
322  *     Free the returned object with g_object_unref().
323  *
324  * Since: 2.22
325  */
326 GSocketAddress *
327 g_socket_connection_get_remote_address (GSocketConnection  *connection,
328                                         GError            **error)
329 {
330   return g_socket_get_remote_address (connection->priv->socket, error);
331 }
332
333 static void
334 g_socket_connection_get_property (GObject    *object,
335                                   guint       prop_id,
336                                   GValue     *value,
337                                   GParamSpec *pspec)
338 {
339   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
340
341   switch (prop_id)
342     {
343      case PROP_SOCKET:
344       g_value_set_object (value, connection->priv->socket);
345       break;
346
347      default:
348       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
349     }
350 }
351
352 static void
353 g_socket_connection_set_property (GObject      *object,
354                                   guint         prop_id,
355                                   const GValue *value,
356                                   GParamSpec   *pspec)
357 {
358   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
359
360   switch (prop_id)
361     {
362      case PROP_SOCKET:
363       connection->priv->socket = G_SOCKET (g_value_dup_object (value));
364       break;
365
366      default:
367       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
368     }
369 }
370
371 static void
372 g_socket_connection_constructed (GObject *object)
373 {
374   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
375
376   g_assert (connection->priv->socket != NULL);
377 }
378
379 static void
380 g_socket_connection_dispose (GObject *object)
381 {
382   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
383
384   connection->priv->in_dispose = TRUE;
385
386   G_OBJECT_CLASS (g_socket_connection_parent_class)
387     ->dispose (object);
388
389   connection->priv->in_dispose = FALSE;
390 }
391
392 static void
393 g_socket_connection_finalize (GObject *object)
394 {
395   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
396
397   if (connection->priv->input_stream)
398     g_object_unref (connection->priv->input_stream);
399
400   if (connection->priv->output_stream)
401     g_object_unref (connection->priv->output_stream);
402
403   g_object_unref (connection->priv->socket);
404
405   G_OBJECT_CLASS (g_socket_connection_parent_class)
406     ->finalize (object);
407 }
408
409 static void
410 g_socket_connection_class_init (GSocketConnectionClass *klass)
411 {
412   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
413   GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass);
414
415   g_type_class_add_private (klass, sizeof (GSocketConnectionPrivate));
416
417   gobject_class->set_property = g_socket_connection_set_property;
418   gobject_class->get_property = g_socket_connection_get_property;
419   gobject_class->constructed = g_socket_connection_constructed;
420   gobject_class->finalize = g_socket_connection_finalize;
421   gobject_class->dispose = g_socket_connection_dispose;
422
423   stream_class->get_input_stream = g_socket_connection_get_input_stream;
424   stream_class->get_output_stream = g_socket_connection_get_output_stream;
425   stream_class->close_fn = g_socket_connection_close;
426   stream_class->close_async = g_socket_connection_close_async;
427   stream_class->close_finish = g_socket_connection_close_finish;
428
429   g_object_class_install_property (gobject_class,
430                                    PROP_SOCKET,
431                                    g_param_spec_object ("socket",
432                                                         P_("Socket"),
433                                                         P_("The underlying GSocket"),
434                                                         G_TYPE_SOCKET,
435                                                         G_PARAM_CONSTRUCT_ONLY |
436                                                         G_PARAM_READWRITE |
437                                                         G_PARAM_STATIC_STRINGS));
438 }
439
440 static void
441 g_socket_connection_init (GSocketConnection *connection)
442 {
443   connection->priv = G_TYPE_INSTANCE_GET_PRIVATE (connection,
444                                                   G_TYPE_SOCKET_CONNECTION,
445                                                   GSocketConnectionPrivate);
446 }
447
448 static gboolean
449 g_socket_connection_close (GIOStream     *stream,
450                            GCancellable  *cancellable,
451                            GError       **error)
452 {
453   GSocketConnection *connection = G_SOCKET_CONNECTION (stream);
454
455   if (connection->priv->output_stream)
456     g_output_stream_close (connection->priv->output_stream,
457                            cancellable, NULL);
458   if (connection->priv->input_stream)
459     g_input_stream_close (connection->priv->input_stream,
460                           cancellable, NULL);
461
462   /* Don't close the underlying socket if this is being called
463    * as part of dispose(); when destroying the GSocketConnection,
464    * we only want to close the socket if we're holding the last
465    * reference on it, and in that case it will close itself when
466    * we unref it in finalize().
467    */
468   if (connection->priv->in_dispose)
469     return TRUE;
470
471   return g_socket_close (connection->priv->socket, error);
472 }
473
474
475 static void
476 g_socket_connection_close_async (GIOStream           *stream,
477                                  int                  io_priority,
478                                  GCancellable        *cancellable,
479                                  GAsyncReadyCallback  callback,
480                                  gpointer             user_data)
481 {
482   GSimpleAsyncResult *res;
483   GIOStreamClass *class;
484   GError *error;
485
486   class = G_IO_STREAM_GET_CLASS (stream);
487
488   /* socket close is not blocked, just do it! */
489   error = NULL;
490   if (class->close_fn &&
491       !class->close_fn (stream, cancellable, &error))
492     {
493       g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
494                                             callback, user_data,
495                                             error);
496       return;
497     }
498
499   res = g_simple_async_result_new (G_OBJECT (stream),
500                                    callback,
501                                    user_data,
502                                    g_socket_connection_close_async);
503   g_simple_async_result_complete_in_idle (res);
504   g_object_unref (res);
505 }
506
507 static gboolean
508 g_socket_connection_close_finish (GIOStream     *stream,
509                                   GAsyncResult  *result,
510                                   GError       **error)
511 {
512   return TRUE;
513 }
514
515 typedef struct {
516   GSocketFamily socket_family;
517   GSocketType socket_type;
518   int protocol;
519   GType implementation;
520 } ConnectionFactory;
521
522 static guint
523 connection_factory_hash (gconstpointer key)
524 {
525   const ConnectionFactory *factory = key;
526   guint h;
527
528   h = factory->socket_family ^ (factory->socket_type << 4) ^ (factory->protocol << 8);
529   /* This is likely to be small, so spread over whole
530      hash space to get some distribution */
531   h = h ^ (h << 8) ^ (h << 16) ^ (h << 24);
532
533   return h;
534 }
535
536 static gboolean
537 connection_factory_equal (gconstpointer _a,
538                           gconstpointer _b)
539 {
540   const ConnectionFactory *a = _a;
541   const ConnectionFactory *b = _b;
542
543   if (a->socket_family != b->socket_family)
544     return FALSE;
545
546   if (a->socket_type != b->socket_type)
547     return FALSE;
548
549   if (a->protocol != b->protocol)
550     return FALSE;
551
552   return TRUE;
553 }
554
555 static GHashTable *connection_factories = NULL;
556 G_LOCK_DEFINE_STATIC(connection_factories);
557
558 /**
559  * g_socket_connection_factory_register_type:
560  * @g_type: a #GType, inheriting from %G_TYPE_SOCKET_CONNECTION
561  * @family: a #GSocketFamily
562  * @type: a #GSocketType
563  * @protocol: a protocol id
564  *
565  * Looks up the #GType to be used when creating socket connections on
566  * sockets with the specified @family, @type and @protocol.
567  *
568  * If no type is registered, the #GSocketConnection base type is returned.
569  *
570  * Since: 2.22
571  */
572 void
573 g_socket_connection_factory_register_type (GType         g_type,
574                                            GSocketFamily family,
575                                            GSocketType   type,
576                                            gint          protocol)
577 {
578   ConnectionFactory *factory;
579
580   g_return_if_fail (g_type_is_a (g_type, G_TYPE_SOCKET_CONNECTION));
581
582   G_LOCK (connection_factories);
583
584   if (connection_factories == NULL)
585     connection_factories = g_hash_table_new_full (connection_factory_hash,
586                                                   connection_factory_equal,
587                                                   (GDestroyNotify)g_free,
588                                                   NULL);
589
590   factory = g_new0 (ConnectionFactory, 1);
591   factory->socket_family = family;
592   factory->socket_type = type;
593   factory->protocol = protocol;
594   factory->implementation = g_type;
595
596   g_hash_table_insert (connection_factories,
597                        factory, factory);
598
599   G_UNLOCK (connection_factories);
600 }
601
602 static void
603 init_builtin_types (void)
604 {
605 #ifndef G_OS_WIN32
606   g_type_ensure (G_TYPE_UNIX_CONNECTION);
607 #endif
608   g_type_ensure (G_TYPE_TCP_CONNECTION);
609 }
610
611 /**
612  * g_socket_connection_factory_lookup_type:
613  * @family: a #GSocketFamily
614  * @type: a #GSocketType
615  * @protocol_id: a protocol id
616  *
617  * Looks up the #GType to be used when creating socket connections on
618  * sockets with the specified @family, @type and @protocol_id.
619  *
620  * If no type is registered, the #GSocketConnection base type is returned.
621  *
622  * Returns: a #GType
623  *
624  * Since: 2.22
625  */
626 GType
627 g_socket_connection_factory_lookup_type (GSocketFamily family,
628                                          GSocketType   type,
629                                          gint          protocol_id)
630 {
631   ConnectionFactory *factory, key;
632   GType g_type;
633
634   init_builtin_types ();
635
636   G_LOCK (connection_factories);
637
638   g_type = G_TYPE_SOCKET_CONNECTION;
639
640   if (connection_factories)
641     {
642       key.socket_family = family;
643       key.socket_type = type;
644       key.protocol = protocol_id;
645
646       factory = g_hash_table_lookup (connection_factories, &key);
647       if (factory)
648         g_type = factory->implementation;
649     }
650
651   G_UNLOCK (connection_factories);
652
653   return g_type;
654 }
655
656 /**
657  * g_socket_connection_factory_create_connection:
658  * @socket: a #GSocket
659  *
660  * Creates a #GSocketConnection subclass of the right type for
661  * @socket.
662  *
663  * Returns: (transfer full): a #GSocketConnection
664  *
665  * Since: 2.22
666  */
667 GSocketConnection *
668 g_socket_connection_factory_create_connection (GSocket *socket)
669 {
670   GType type;
671
672   type = g_socket_connection_factory_lookup_type (g_socket_get_family (socket),
673                                                   g_socket_get_socket_type (socket),
674                                                   g_socket_get_protocol (socket));
675   return g_object_new (type, "socket", socket, NULL);
676 }