[gnio/connection-factory] Add source_object to the GSocketListener sources



commit c4c7a2e905a8b2ab31b22768190fd5baa0b0c52e
Author: Alexander Larsson <alexl redhat com>
Date:   Mon May 11 12:12:22 2009 +0200

    Add source_object to the GSocketListener sources
    
    Apps can use this if they want to differentiate between different
    sources. It is a GObject so that we can ref and unref it in a
    threadsafe way.
---
 examples/server.c            |    1 +
 gio/gsocketlistener.c        |   60 ++++++++++++++++++++++++++++++------------
 gio/gsocketlistener.h        |   10 +++++--
 gio/gsocketservice.c         |   23 +++++++--------
 gio/gsocketservice.h         |    2 +-
 gio/gthreadedsocketservice.c |   18 +++++++-----
 gio/gthreadedsocketservice.h |    2 +-
 7 files changed, 75 insertions(+), 41 deletions(-)

diff --git a/examples/server.c b/examples/server.c
index 0833788..62462ed 100644
--- a/examples/server.c
+++ b/examples/server.c
@@ -60,6 +60,7 @@ main (int argc, char *argv[])
 
   if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service),
 					port,
+					NULL,
 					&error))
     {
       g_printerr ("%s: %s\n", argv[0], error->message);
diff --git a/gio/gsocketlistener.c b/gio/gsocketlistener.c
index 8ebdc04..1f3d19c 100644
--- a/gio/gsocketlistener.c
+++ b/gio/gsocketlistener.c
@@ -35,6 +35,8 @@
 
 G_DEFINE_TYPE (GSocketListener, g_socket_listener, G_TYPE_OBJECT);
 
+static GQuark source_quark = 0;
+
 struct _GSocketListenerPrivate
 {
   GPtrArray           *sockets;
@@ -67,6 +69,8 @@ g_socket_listener_class_init (GSocketListenerClass *klass)
   g_type_class_add_private (klass, sizeof (GSocketListenerPrivate));
 
   gobject_class->finalize = g_socket_listener_finalize;
+
+  source_quark = g_quark_from_static_string ("g-socket-listener-source");
 }
 
 static void
@@ -102,6 +106,7 @@ check_listener (GSocketListener *listener,
 gboolean
 g_socket_listener_add_socket (GSocketListener *listener,
 			      GSocket *socket,
+			      GObject *source_object,
 			      GError **error)
 {
   if (!check_listener (listener, error))
@@ -109,8 +114,19 @@ g_socket_listener_add_socket (GSocketListener *listener,
 
   /* TODO: Check that socket it is bound & not closed? */
 
+  if (g_socket_is_closed (socket))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+			   _("Added socket is closed"));
+      return FALSE;
+    }
+
   g_ptr_array_add (listener->priv->sockets, socket);
 
+  if (source_object)
+    g_object_set_qdata_full (G_OBJECT (socket), source_quark,
+			     g_object_ref (source_object), g_object_unref);
+
   return TRUE;
 }
 
@@ -119,6 +135,7 @@ g_socket_listener_add_address (GSocketListener *listener,
 			       GSocketAddress *address,
 			       GSocketType type,
 			       const char *protocol,
+			       GObject *source_object,
 			       GError **error)
 {
   GSocketFamily family;
@@ -134,7 +151,9 @@ g_socket_listener_add_address (GSocketListener *listener,
 
   if (!g_socket_bind (socket, address, error) ||
       !g_socket_listen (socket, error) ||
-      !g_socket_listener_add_socket (listener, socket, error))
+      !g_socket_listener_add_socket (listener, socket,
+				     source_object,
+				     error))
     {
       g_object_unref (socket);
       return FALSE;
@@ -149,6 +168,7 @@ g_socket_listener_add_address (GSocketListener *listener,
 gboolean
 g_socket_listener_add_inet_port (GSocketListener *listener,
 				 int port,
+				 GObject *source_object,
 				 GError **error)
 {
   GSocketAddress *address4, *address6;
@@ -170,6 +190,7 @@ g_socket_listener_add_inet_port (GSocketListener *listener,
 				      address6,
 				      G_SOCKET_TYPE_STREAM,
 				      NULL,
+				      source_object,
 				      NULL))
     {
       /* Failed, to create ipv6, socket, just use ipv4,
@@ -178,6 +199,7 @@ g_socket_listener_add_inet_port (GSocketListener *listener,
 					   address4,
 					   G_SOCKET_TYPE_STREAM,
 					   NULL,
+					   source_object,
 					   error);
     }
   else
@@ -189,6 +211,7 @@ g_socket_listener_add_inet_port (GSocketListener *listener,
 				     address4,
 				     G_SOCKET_TYPE_STREAM,
 				     NULL,
+				     source_object,
 				     NULL);
     }
 
@@ -261,7 +284,7 @@ accept_callback (GSocket *socket,
 GSocket *
 g_socket_listener_accept_socket (GSocketListener  *listener,
 				 GCancellable     *cancellable,
-				 GSocket         **source,
+				 GObject         **source_object,
 				 GError          **error)
 {
   GSocket *accept_socket, *socket;
@@ -303,8 +326,8 @@ g_socket_listener_accept_socket (GSocketListener  *listener,
   if (!(socket = g_socket_accept (accept_socket, error)))
     return NULL;
 
-  if (source)
-    *source = accept_socket;
+  if (source_object)
+    *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
 
   return socket;
 }
@@ -312,6 +335,7 @@ g_socket_listener_accept_socket (GSocketListener  *listener,
 GSocketConnection *
 g_socket_listener_accept (GSocketListener  *listener,
 			  GCancellable     *cancellable,
+			  GObject         **source_object,
 			  GError          **error)
 {
   GSocketConnection *connection;
@@ -319,7 +343,7 @@ g_socket_listener_accept (GSocketListener  *listener,
 
   socket = g_socket_listener_accept_socket (listener,
 					    cancellable,
-					    NULL,
+					    source_object,
 					    error);
   if (socket == NULL)
     return NULL;
@@ -348,16 +372,18 @@ accept_ready (GSocket *accept_socket,
                                              &error))
     {
       GSocket *socket;
+      GObject *source_object;
 
       socket = g_socket_accept (accept_socket, &error);
       if (socket)
 	{
 	  g_simple_async_result_set_op_res_gpointer (data->simple, socket,
 						     g_object_unref);
-	  g_object_set_data_full (G_OBJECT (data->simple),
-				  "accept-socket",
-				  g_object_ref (accept_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),
+				     source_quark,
+				     g_object_ref (source_object), g_object_unref);
 	}
     }
 
@@ -407,10 +433,10 @@ g_socket_listener_accept_socket_async (GSocketListener      *listener,
 }
 
 GSocket *
-g_socket_listener_accept_socket_finish (GSocketListener      *listener,
-					GAsyncResult         *result,
-					GSocket             **source,
-					GError              **error)
+g_socket_listener_accept_socket_finish (GSocketListener   *listener,
+					GAsyncResult      *result,
+					GObject          **source_object,
+					GError           **error)
 {
   GSocket *socket;
   GSimpleAsyncResult *simple;
@@ -426,8 +452,8 @@ g_socket_listener_accept_socket_finish (GSocketListener      *listener,
 
   socket = g_simple_async_result_get_op_res_gpointer (simple);
 
-  if (source)
-    *source = g_object_ref (g_object_get_data (G_OBJECT (simple), "accept-socket"));
+  if (source_object)
+    *source_object = g_object_get_qdata (G_OBJECT (result), source_quark);
 
   return g_object_ref (socket);
 }
@@ -447,7 +473,7 @@ g_socket_listener_accept_async (GSocketListener     *listener,
 GSocketConnection *
 g_socket_listener_accept_finish (GSocketListener *listener,
 				 GAsyncResult *result,
-				 GSocket **source,
+				 GObject **source_object,
 				 GError **error)
 {
   GSocket *socket;
@@ -455,7 +481,7 @@ g_socket_listener_accept_finish (GSocketListener *listener,
 
   socket = g_socket_listener_accept_socket_finish (listener,
 						   result,
-						   source,
+						   source_object,
 						   error);
   if (socket == NULL)
     return NULL;
diff --git a/gio/gsocketlistener.h b/gio/gsocketlistener.h
index c9f6e71..66f3829 100644
--- a/gio/gsocketlistener.h
+++ b/gio/gsocketlistener.h
@@ -63,19 +63,22 @@ GSocketListener *       g_socket_listener_new                           (void);
 
 gboolean                g_socket_listener_add_socket                    (GSocketListener     *listener,
                                                                          GSocket             *socket,
+									 GObject             *source_object,
 									 GError             **error);
 gboolean                g_socket_listener_add_address                   (GSocketListener      *listener,
                                                                          GSocketAddress      *address,
 									 GSocketType          type,
 									 const char          *protocol,
+									 GObject             *source_object,
 									 GError             **error);
 gboolean                g_socket_listener_add_inet_port                 (GSocketListener      *listener,
                                                                          int                  port,
+									 GObject             *source_object,
 									 GError             **error);
 
 GSocket *               g_socket_listener_accept_socket                 (GSocketListener      *listener,
                                                                          GCancellable         *cancellable,
-									 GSocket             **source,
+									 GObject             **source_object,
                                                                          GError              **error);
 void                    g_socket_listener_accept_socket_async           (GSocketListener      *listener,
                                                                          GCancellable         *cancellable,
@@ -83,12 +86,13 @@ void                    g_socket_listener_accept_socket_async           (GSocket
                                                                          gpointer              user_data);
 GSocket *               g_socket_listener_accept_socket_finish          (GSocketListener      *listener,
                                                                          GAsyncResult         *result,
-									 GSocket             **source,
+									 GObject             **source_object,
                                                                          GError              **error);
 
 
 GSocketConnection *     g_socket_listener_accept                        (GSocketListener      *listener,
                                                                          GCancellable         *cancellable,
+									 GObject             **source_object,
                                                                          GError              **error);
 
 void                    g_socket_listener_accept_async                  (GSocketListener      *listener,
@@ -98,7 +102,7 @@ void                    g_socket_listener_accept_async                  (GSocket
 
 GSocketConnection *     g_socket_listener_accept_finish                 (GSocketListener      *listener,
                                                                          GAsyncResult         *result,
-									 GSocket             **source,
+									 GObject             **source_object,
                                                                          GError              **error);
 
 void                    g_socket_listener_close                         (GSocketListener      *listener);
diff --git a/gio/gsocketservice.c b/gio/gsocketservice.c
index 36ea813..47e7816 100644
--- a/gio/gsocketservice.c
+++ b/gio/gsocketservice.c
@@ -59,7 +59,7 @@ static void g_socket_service_ready (GObject      *object,
 static gboolean
 g_socket_service_real_incoming (GSocketService    *service,
                                 GSocketConnection *connection,
-                                GSocket           *source_socket)
+                                GObject           *source_object)
 {
   return FALSE;
 }
@@ -85,7 +85,7 @@ g_socket_service_finalize (GObject *object)
 }
 
 static void
-g_socket_service_changed (GSocketListener   *listener)
+g_socket_service_changed (GSocketListener *listener)
 {
   GSocketService  *service = G_SOCKET_SERVICE (listener);
 
@@ -100,12 +100,12 @@ g_socket_service_changed (GSocketListener   *listener)
 static gboolean
 g_socket_service_incoming (GSocketService    *service,
                            GSocketConnection *connection,
-                           GSocket           *source_socket)
+                           GObject           *source_object)
 {
   gboolean result;
 
   g_signal_emit (service, g_socket_service_incoming_signal,
-                 0, connection, source_socket, &result);
+                 0, connection, source_object, &result);
   return result;
 }
 
@@ -125,7 +125,7 @@ g_socket_service_class_init (GSocketServiceClass *class)
    * GSocketService::incoming:
    * @service: the #GSocketService.
    * @connection: a new #GSocketConnection object.
-   * @source_socket: the #GSocket whence @connection was accepted.
+   * @source_object: the source_object passed to g_socket_listener_add_address().
    * @returns: %TRUE if @connection has been handled.
    *
    * The ::incoming signal is emitted when a new incoming connection
@@ -140,7 +140,7 @@ g_socket_service_class_init (GSocketServiceClass *class)
                   G_STRUCT_OFFSET (GSocketServiceClass, incoming),
                   g_signal_accumulator_true_handled, NULL,
                   _gnio_marshal_BOOLEAN__OBJECT_OBJECT, G_TYPE_BOOLEAN,
-                  2, G_TYPE_SOCKET_CONNECTION, G_TYPE_SOCKET);
+                  2, G_TYPE_SOCKET_CONNECTION, G_TYPE_OBJECT);
 }
 
 static void
@@ -151,10 +151,10 @@ g_socket_service_ready (GObject      *object,
   GSocketListener *listener = G_SOCKET_LISTENER (object);
   GSocketService *service = G_SOCKET_SERVICE (object);
   GSocketConnection *connection;
-  GSocket *source;
+  GObject *source_object;
   GError *error = NULL;
 
-  connection = g_socket_listener_accept_finish (listener, result, &source, &error);
+  connection = g_socket_listener_accept_finish (listener, result, &source_object, &error);
   if (error)
     {
       if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
@@ -165,14 +165,13 @@ g_socket_service_ready (GObject      *object,
     }
   else
     {
-      g_socket_service_incoming (service, connection, source);
+      g_socket_service_incoming (service, connection, source_object);
       g_object_unref (connection);
-      g_object_unref (source);
     }
 
   /* requeue */
-  g_socket_listener_accept_async (listener, NULL,
-                                  g_socket_service_ready, service);
+  g_socket_listener_accept_async (listener, service->priv->cancellable,
+                                  g_socket_service_ready, NULL);
 }
 
 
diff --git a/gio/gsocketservice.h b/gio/gsocketservice.h
index cae3eef..ff209b2 100644
--- a/gio/gsocketservice.h
+++ b/gio/gsocketservice.h
@@ -44,7 +44,7 @@ struct _GSocketServiceClass
 
   gboolean (* incoming) (GSocketService    *service,
                          GSocketConnection *connection,
-			 GSocket           *source_socket);
+			 GObject           *source_object);
   gpointer padding[6];
 };
 
diff --git a/gio/gthreadedsocketservice.c b/gio/gthreadedsocketservice.c
index bc85d1b..2e2e962 100644
--- a/gio/gthreadedsocketservice.c
+++ b/gio/gthreadedsocketservice.c
@@ -42,7 +42,7 @@ typedef struct
 {
   GThreadedSocketService *service;
   GSocketConnection *connection;
-  GSocket *source_socket;
+  GObject *source_object;
 } GThreadedSocketServiceData;
 
 static gpointer
@@ -52,11 +52,12 @@ g_threaded_socket_service_func (gpointer user_data)
   gboolean result;
 
   g_signal_emit (data->service, g_threaded_socket_service_run_signal,
-                 0, data->connection, data->source_socket, &result);
+                 0, data->connection, data->source_object, &result);
 
   g_object_unref (data->service);
   g_object_unref (data->connection);
-  g_object_unref (data->source_socket);
+  if (data->source_object)
+    g_object_unref (data->source_object);
   g_slice_free (GThreadedSocketServiceData, data);
 
   return NULL;
@@ -65,14 +66,17 @@ g_threaded_socket_service_func (gpointer user_data)
 static gboolean
 g_threaded_socket_service_incoming (GSocketService    *service,
                                     GSocketConnection *connection,
-                                    GSocket           *source_socket)
+                                    GObject           *source_object)
 {
   GThreadedSocketServiceData *data;
 
   data = g_slice_new (GThreadedSocketServiceData);
   data->service = g_object_ref (service);
   data->connection = g_object_ref (connection);
-  data->source_socket = g_object_ref (source_socket);
+  if (source_object)
+    data->source_object = g_object_ref (source_object);
+  else
+    data->source_object = NULL;
 
   g_thread_create (g_threaded_socket_service_func, data, FALSE, NULL);
   return FALSE;
@@ -94,7 +98,7 @@ g_threaded_socket_service_class_init (GThreadedSocketServiceClass *class)
    * GThreadedSocketService::run:
    * @service: the #GThreadedSocketService.
    * @connection: a new #GSocketConnection object.
-   * @listener: the #GSocketListener whence @connection originated.
+   * @source_object: the source_object passed to g_socket_listener_add_address().
    * @returns: %TRUE if @connection has been handled.
    *
    * The ::run signal is emitted in a worker thread in response to an
@@ -109,7 +113,7 @@ g_threaded_socket_service_class_init (GThreadedSocketServiceClass *class)
                   G_STRUCT_OFFSET (GThreadedSocketServiceClass, run),
                   g_signal_accumulator_true_handled, NULL,
                   _gnio_marshal_BOOLEAN__OBJECT_OBJECT, G_TYPE_BOOLEAN,
-                  2, G_TYPE_SOCKET_CONNECTION, G_TYPE_SOCKET);
+                  2, G_TYPE_SOCKET_CONNECTION, G_TYPE_OBJECT);
 }
 
 /**
diff --git a/gio/gthreadedsocketservice.h b/gio/gthreadedsocketservice.h
index d0fe165..ba80aa3 100644
--- a/gio/gthreadedsocketservice.h
+++ b/gio/gthreadedsocketservice.h
@@ -47,7 +47,7 @@ struct _GThreadedSocketServiceClass
 
   gboolean (* run) (GThreadedSocketService *service,
                     GSocketConnection      *connection,
-                    GSocket                *source_socket);
+                    GObject                *source_object);
 };
 
 struct _GThreadedSocketService



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]