X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgsocketlistener.c;h=7185745ff170b2ad867a8190c0374a74b9dcba8a;hb=2a2b11b1bb6c702d6b2ef1c37524a57688a94a4e;hp=adbac5c29e3090fb780d83eef1ce6f266e03ee60;hpb=8e2fa44953f1f92afdb198bb3ff8b98bb4cf6699;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gsocketlistener.c b/gio/gsocketlistener.c index adbac5c..7185745 100644 --- a/gio/gsocketlistener.c +++ b/gio/gsocketlistener.c @@ -15,9 +15,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Authors: Christian Kellner * Samuel Cormier-Iijima @@ -28,7 +26,7 @@ #include "config.h" #include "gsocketlistener.h" -#include +#include #include #include #include @@ -38,12 +36,12 @@ #include #include "glibintl.h" -#include "gioalias.h" /** - * SECTION: gsocketlistener + * SECTION:gsocketlistener * @title: GSocketListener * @short_description: Helper for accepting network client connections + * @include: gio/gio.h * @see_also: #GThreadedSocketService, #GSocketService. * * A #GSocketListener is an object that keeps track of a set @@ -57,8 +55,6 @@ * Since: 2.22 */ -G_DEFINE_TYPE (GSocketListener, g_socket_listener, G_TYPE_OBJECT); - enum { PROP_0, @@ -76,6 +72,8 @@ struct _GSocketListenerPrivate guint closed : 1; }; +G_DEFINE_TYPE_WITH_PRIVATE (GSocketListener, g_socket_listener, G_TYPE_OBJECT) + static void g_socket_listener_finalize (GObject *object) { @@ -84,9 +82,11 @@ g_socket_listener_finalize (GObject *object) if (listener->priv->main_context) g_main_context_unref (listener->priv->main_context); - if (!listener->priv->closed) - g_socket_listener_close (listener); - + /* Do not explicitly close the sockets. Instead, let them close themselves if + * their final reference is dropped, but keep them open if a reference is + * held externally to the GSocketListener (which is possible if + * g_socket_listener_add_socket() was used). + */ g_ptr_array_free (listener->priv->sockets, TRUE); G_OBJECT_CLASS (g_socket_listener_parent_class) @@ -137,8 +137,6 @@ g_socket_listener_class_init (GSocketListenerClass *klass) { GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass); - g_type_class_add_private (klass, sizeof (GSocketListenerPrivate)); - gobject_class->finalize = g_socket_listener_finalize; gobject_class->set_property = g_socket_listener_set_property; gobject_class->get_property = g_socket_listener_get_property; @@ -157,9 +155,7 @@ g_socket_listener_class_init (GSocketListenerClass *klass) static void g_socket_listener_init (GSocketListener *listener) { - listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener, - G_TYPE_SOCKET_LISTENER, - GSocketListenerPrivate); + listener->priv = g_socket_listener_get_instance_private (listener); listener->priv->sockets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); listener->priv->listen_backlog = 10; @@ -200,7 +196,7 @@ check_listener (GSocketListener *listener, * g_socket_listener_add_socket: * @listener: a #GSocketListener * @socket: a listening #GSocket - * @source_object: Optional #GObject identifying this source + * @source_object: (allow-none): Optional #GObject identifying this source * @error: #GError for error reporting, or %NULL to ignore. * * Adds @socket to the set of sockets that we try to accept @@ -212,6 +208,11 @@ check_listener (GSocketListener *listener, * useful if you're listening on multiple addresses and do * different things depending on what address is connected to. * + * The @socket will not be automatically closed when the @listener is finalized + * unless the listener held the final reference to the socket. Before GLib 2.42, + * the @socket was automatically closed on finalization of the @listener, even + * if references to it were held elsewhere. + * * Returns: %TRUE on success, %FALSE on error. * * Since: 2.22 @@ -254,8 +255,8 @@ g_socket_listener_add_socket (GSocketListener *listener, * @address: a #GSocketAddress * @type: a #GSocketType * @protocol: a #GSocketProtocol - * @source_object: Optional #GObject identifying this source - * @effective_address: location to store the address that was bound to, or %NULL. + * @source_object: (allow-none): Optional #GObject identifying this source + * @effective_address: (out) (allow-none): location to store the address that was bound to, or %NULL. * @error: #GError for error reporting, or %NULL to ignore. * * Creates a socket of type @type and protocol @protocol, binds @@ -264,7 +265,7 @@ g_socket_listener_add_socket (GSocketListener *listener, * * Note that adding an IPv6 address, depending on the platform, * may or may not result in a listener that also accepts IPv4 - * connections. For more determinstic behaviour, see + * connections. For more deterministic behavior, see * g_socket_listener_add_inet_port(). * * @source_object will be passed out in the various calls @@ -273,7 +274,7 @@ g_socket_listener_add_socket (GSocketListener *listener, * different things depending on what address is connected to. * * If successful and @effective_address is non-%NULL then it will - * be set to the address that the binding actually occured at. This + * be set to the address that the binding actually occurred at. This * is helpful for determining the port number that was used for when * requesting a binding to port 0 (ie: "any port"). This address, if * requested, belongs to the caller and must be freed. @@ -345,7 +346,7 @@ g_socket_listener_add_address (GSocketListener *listener, * g_socket_listener_add_inet_port: * @listener: a #GSocketListener * @port: an IP port number (non-zero) - * @source_object: Optional #GObject identifying this source + * @source_object: (allow-none): Optional #GObject identifying this source * @error: #GError for error reporting, or %NULL to ignore. * * Helper function for g_socket_listener_add_address() that @@ -563,8 +564,8 @@ accept_callback (GSocket *socket, /** * g_socket_listener_accept_socket: * @listener: a #GSocketListener - * @source_object: location where #GObject pointer will be stored, or %NULL - * @cancellable: optional #GCancellable object, %NULL to ignore. + * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL. + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. * @error: #GError for error reporting, or %NULL to ignore. * * Blocks waiting for a client to connect to any of the sockets added @@ -582,7 +583,7 @@ accept_callback (GSocket *socket, * triggering the cancellable object from another thread. If the operation * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. * - * Returns: a #GSocket on success, %NULL on error. + * Returns: (transfer full): a #GSocket on success, %NULL on error. * * Since: 2.22 */ @@ -640,8 +641,8 @@ g_socket_listener_accept_socket (GSocketListener *listener, /** * g_socket_listener_accept: * @listener: a #GSocketListener - * @source_object: location where #GObject pointer will be stored, or %NULL - * @cancellable: optional #GCancellable object, %NULL to ignore. + * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. * @error: #GError for error reporting, or %NULL to ignore. * * Blocks waiting for a client to connect to any of the sockets added @@ -656,7 +657,7 @@ g_socket_listener_accept_socket (GSocketListener *listener, * triggering the cancellable object from another thread. If the operation * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. * - * Returns: a #GSocketConnection on success, %NULL on error. + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. * * Since: 2.22 */ @@ -682,53 +683,41 @@ g_socket_listener_accept (GSocketListener *listener, return connection; } -struct AcceptAsyncData { - GSimpleAsyncResult *simple; - GCancellable *cancellable; - GList *sources; -}; - static gboolean accept_ready (GSocket *accept_socket, GIOCondition condition, - gpointer _data) + gpointer user_data) { - struct AcceptAsyncData *data = _data; + GTask *task = user_data; GError *error = NULL; GSocket *socket; GObject *source_object; - socket = g_socket_accept (accept_socket, data->cancellable, &error); + socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error); if (socket) { - g_simple_async_result_set_op_res_gpointer (data->simple, socket, - g_object_unref); source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark); if (source_object) - g_object_set_qdata_full (G_OBJECT (data->simple), + g_object_set_qdata_full (G_OBJECT (task), source_quark, g_object_ref (source_object), g_object_unref); + g_task_return_pointer (task, socket, g_object_unref); } else { - g_simple_async_result_set_from_error (data->simple, error); - g_error_free (error); + g_task_return_error (task, error); } - g_simple_async_result_complete_in_idle (data->simple); - g_object_unref (data->simple); - free_sources (data->sources); - g_free (data); - + g_object_unref (task); return FALSE; } /** * g_socket_listener_accept_socket_async: * @listener: a #GSocketListener - * @cancellable: a #GCancellable, or %NULL - * @callback: a #GAsyncReadyCallback - * @user_data: user data for the callback + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data for the callback * * This is the asynchronous version of g_socket_listener_accept_socket(). * @@ -744,41 +733,38 @@ g_socket_listener_accept_socket_async (GSocketListener *listener, GAsyncReadyCallback callback, gpointer user_data) { - struct AcceptAsyncData *data; + GTask *task; + GList *sources; GError *error = NULL; + task = g_task_new (listener, cancellable, callback, user_data); + if (!check_listener (listener, &error)) { - g_simple_async_report_gerror_in_idle (G_OBJECT (listener), - callback, user_data, - error); - g_error_free (error); + g_task_return_error (task, error); + g_object_unref (task); return; } - data = g_new0 (struct AcceptAsyncData, 1); - data->simple = g_simple_async_result_new (G_OBJECT (listener), - callback, user_data, - g_socket_listener_accept_socket_async); - data->cancellable = cancellable; - data->sources = add_sources (listener, - accept_ready, - data, - cancellable, - g_main_context_get_thread_default ()); + sources = add_sources (listener, + accept_ready, + task, + cancellable, + g_main_context_get_thread_default ()); + g_task_set_task_data (task, sources, (GDestroyNotify) free_sources); } /** * g_socket_listener_accept_socket_finish: * @listener: a #GSocketListener * @result: a #GAsyncResult. - * @source_object: Optional #GObject identifying this source - * @error: a #GError location to store the error occuring, or %NULL to + * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source + * @error: a #GError location to store the error occurring, or %NULL to * ignore. * * Finishes an async accept operation. See g_socket_listener_accept_socket_async() * - * Returns: a #GSocket on success, %NULL on error. + * Returns: (transfer full): a #GSocket on success, %NULL on error. * * Since: 2.22 */ @@ -788,32 +774,21 @@ g_socket_listener_accept_socket_finish (GSocketListener *listener, GObject **source_object, GError **error) { - GSocket *socket; - GSimpleAsyncResult *simple; - - g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_listener_accept_socket_async); - - socket = g_simple_async_result_get_op_res_gpointer (simple); + g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL); + g_return_val_if_fail (g_task_is_valid (result, listener), NULL); if (source_object) *source_object = g_object_get_qdata (G_OBJECT (result), source_quark); - return g_object_ref (socket); + return g_task_propagate_pointer (G_TASK (result), error); } /** * g_socket_listener_accept_async: * @listener: a #GSocketListener - * @cancellable: a #GCancellable, or %NULL - * @callback: a #GAsyncReadyCallback - * @user_data: user data for the callback + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data for the callback * * This is the asynchronous version of g_socket_listener_accept(). * @@ -839,13 +814,13 @@ g_socket_listener_accept_async (GSocketListener *listener, * g_socket_listener_accept_finish: * @listener: a #GSocketListener * @result: a #GAsyncResult. - * @source_object: Optional #GObject identifying this source - * @error: a #GError location to store the error occuring, or %NULL to + * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source + * @error: a #GError location to store the error occurring, or %NULL to * ignore. * * Finishes an async accept operation. See g_socket_listener_accept_async() * - * Returns: a #GSocketConnection on success, %NULL on error. + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. * * Since: 2.22 */ @@ -930,12 +905,12 @@ g_socket_listener_close (GSocketListener *listener) /** * g_socket_listener_add_any_inet_port: * @listener: a #GSocketListener - * @source_object: Optional #GObject identifying this source - * @error: a #GError location to store the error occuring, or %NULL to + * @source_object: (allow-none): Optional #GObject identifying this source + * @error: a #GError location to store the error occurring, or %NULL to * ignore. * * Listens for TCP connections on any available port number for both - * IPv6 and IPv4 (if each are available). + * IPv6 and IPv4 (if each is available). * * This is useful if you need to have a socket for incoming connections * but don't care about the specific port number. @@ -1151,6 +1126,3 @@ g_socket_listener_add_any_inet_port (GSocketListener *listener, return candidate_port; } - -#define __G_SOCKET_LISTENER_C__ -#include "gioaliasdef.c"