[gnio/connection-factory] Re-imagining GSocketListener



commit 0c236bb6a6437af2ae3fa8f60f109c228f36c02a
Author: Alexander Larsson <alexl redhat com>
Date:   Sat May 9 22:28:42 2009 +0200

    Re-imagining GSocketListener
    
    We now support multiple sockets in each listener. This way we can
    handle the ipv6+ipv4 linux vs non-linux issue nicely (you need 1 socket
    on linux, 2 on other platforms).
    
    We also remove the not very useful subclasses by pushing socket factory
    to the base class and adding a helper function for the inet port case.
    
    We also add support for listening and then accepting a socket, instead of
    always getting a connection, as this may be useful in some cases.
    
    examples/server.c is updated to work with the new APIs
---
 examples/server.c     |   17 ++-
 gio/Makefile.am       |    8 +-
 gio/gnio.h            |    2 -
 gio/gsocket.c         |    3 +-
 gio/gsocketlistener.c |  476 +++++++++++++++++++++++++++++++++++++------------
 gio/gsocketlistener.h |   37 +++-
 gio/gtcplistener.c    |  189 -------------------
 gio/gtcplistener.h    |   57 ------
 gio/gunixlistener.c   |  125 -------------
 gio/gunixlistener.h   |   57 ------
 10 files changed, 405 insertions(+), 566 deletions(-)

diff --git a/examples/server.c b/examples/server.c
index 597b581..51d4566 100644
--- a/examples/server.c
+++ b/examples/server.c
@@ -44,6 +44,7 @@ main (int argc, char *argv[])
   GSocketService *service;
   GOptionContext *context;
   GError *error = NULL;
+  GSocketListener *listener;
 
   g_type_init ();
   g_thread_init (NULL);
@@ -58,11 +59,17 @@ main (int argc, char *argv[])
 
   service = g_threaded_socket_service_new ();
 
-  {
-    GSocketListener *tcp = g_tcp_listener_new (port);
-    g_socket_service_add_listener (service, tcp);
-    g_object_unref (tcp);
-  }
+  listener = g_socket_listener_new ();
+  if (!g_socket_listener_add_inet_port (listener,
+					port,
+					&error))
+    {
+      g_printerr ("%s: %s\n", argv[0], error->message);
+      return 1;
+    }
+
+  g_socket_service_add_listener (service, listener);
+  g_object_unref (listener);
 
   g_print ("Echo service listening on port %d\n", port);
 
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 672d3e4..ce38509 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -26,14 +26,12 @@ sources = \
 	gsocketoutputstream.h		\
 	gsocketservice.c		\
 	gtcpconnection.c		\
-	gtcplistener.c			\
 	gthreadedsocketservice.c
 
 if OS_UNIX
 unix_sources = \
 	gunixconnection.c		\
-	gunixfdmessage.c		\
-	gunixlistener.c
+	gunixfdmessage.c
 else
 unix_sources =
 endif
@@ -60,11 +58,9 @@ headers = \
 	gsocketlistener.h		\
 	gsocketservice.h		\
 	gtcpconnection.h		\
-	gtcplistener.h			\
 	gthreadedsocketservice.h	\
 	gunixfdmessage.h		\
-	gunixconnection.h		\
-	gunixlistener.h
+	gunixconnection.h
 
 gioinclude_HEADERS = $(headers) gnioenums.h
 
diff --git a/gio/gnio.h b/gio/gnio.h
index 3bde0a3..239df7c 100644
--- a/gio/gnio.h
+++ b/gio/gnio.h
@@ -31,11 +31,9 @@
 #include <gio/gsocketlistener.h>
 #include <gio/gsocketservice.h>
 #include <gio/gtcpconnection.h>
-#include <gio/gtcplistener.h>
 #include <gio/gthreadedsocketservice.h>
 #include <gio/gtls.h>
 #include <gio/gunixconnection.h>
-#include <gio/gunixlistener.h>
 
 #undef __GIO_GIO_H_INSIDE__
 
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 5f0cfc9..41dab8b 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -2231,7 +2231,8 @@ g_socket_create_source (GSocket      *socket,
 #ifdef G_OS_WIN32
   source = winsock_source_new (socket, condition, cancellable);
 #else
-  source =_g_fd_source_new (socket->priv->fd, condition, cancellable);
+  source =_g_fd_source_new_with_object (G_OBJECT (socket), socket->priv->fd,
+					condition, cancellable);
 #endif
   return source;
 }
diff --git a/gio/gsocketlistener.c b/gio/gsocketlistener.c
index a0fe37b..2df057c 100644
--- a/gio/gsocketlistener.c
+++ b/gio/gsocketlistener.c
@@ -25,54 +25,41 @@
 
 #include "gsocketlistener.h"
 
+#include "config.h"
 #include <gio/gsimpleasyncresult.h>
 #include <gio/gcancellable.h>
+#include <gio/gioerror.h>
+#include <gio/ginetaddress.h>
+#include <gio/ginetsocketaddress.h>
 #include "gsocket.h"
 
-G_DEFINE_ABSTRACT_TYPE (GSocketListener, g_socket_listener, G_TYPE_OBJECT);
+G_DEFINE_TYPE (GSocketListener, g_socket_listener, G_TYPE_OBJECT);
 
 struct _GSocketListenerPrivate
 {
-  GSocket            *socket;
-  GError             *error;
-
-  GSimpleAsyncResult *result;
-  GCancellable       *cancellable;
-  gboolean            from_mainloop;
+  GPtrArray           *sockets;
+  GMainContext        *main_context;
+  guint               closed : 1;
 };
 
 static void
 g_socket_listener_finalize (GObject *object)
 {
-  GSocketListener *server = G_SOCKET_LISTENER (object);
+  GSocketListener *listener = G_SOCKET_LISTENER (object);
 
-  if (server->priv->socket)
-    g_object_unref (server->priv->socket);
+  if (listener->priv->main_context)
+    g_main_context_unref (listener->priv->main_context);
 
-  if (server->priv->error)
-    g_error_free (server->priv->error);
+  if (!listener->priv->closed)
+    g_socket_listener_close (listener);
 
-  /* the GSimpleAsyncResult maintains a ref to us.
-   * if it's non-null, we have a serious problem...
-   */
-  g_assert (server->priv->cancellable == NULL);
-  g_assert (server->priv->result == NULL);
+  g_ptr_array_free (listener->priv->sockets, TRUE);
 
   G_OBJECT_CLASS (g_socket_listener_parent_class)
     ->finalize (object);
 }
 
 static void
-g_socket_listener_construct (GObject *object)
-{
-  GSocketListener *listener = G_SOCKET_LISTENER (object);
-  GSocketListenerClass *class = G_SOCKET_LISTENER_GET_CLASS (listener);
-
-  listener->priv->socket = class->socket_factory (listener,
-                                                  &listener->priv->error);
-}
-
-static void
 g_socket_listener_class_init (GSocketListenerClass *klass)
 {
   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
@@ -80,160 +67,415 @@ g_socket_listener_class_init (GSocketListenerClass *klass)
   g_type_class_add_private (klass, sizeof (GSocketListenerPrivate));
 
   gobject_class->finalize = g_socket_listener_finalize;
-  gobject_class->constructed = g_socket_listener_construct;
 }
 
 static void
-g_socket_listener_init (GSocketListener *server)
+g_socket_listener_init (GSocketListener *listener)
 {
-  server->priv = G_TYPE_INSTANCE_GET_PRIVATE (server,
-                                              G_TYPE_SOCKET_LISTENER,
-                                              GSocketListenerPrivate);
+  listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener,
+						G_TYPE_SOCKET_LISTENER,
+						GSocketListenerPrivate);
+  listener->priv->sockets =
+    g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
 }
 
-GSocketConnection *
-g_socket_listener_accept (GSocketListener  *listener,
-                          GCancellable     *cancellable,
-                          GError          **error)
+GSocketListener *
+g_socket_listener_new (void)
 {
+  return g_object_new (G_TYPE_SOCKET_LISTENER, NULL);
+}
+
+static gboolean
+check_listener (GSocketListener *listener,
+		GError **error)
+{
+  if (listener->priv->closed)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
+			   _("Listener is already closed"));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+g_socket_listener_add_socket (GSocketListener *listener,
+			      GSocket *socket,
+			      GError **error)
+{
+  if (!check_listener (listener, error))
+    return FALSE;
+
+  /* TODO: Check that socket it is bound & not closed? */
+
+  g_ptr_array_add (listener->priv->sockets, socket);
+
+  return TRUE;
+}
+
+gboolean
+g_socket_listener_add_address (GSocketListener *listener,
+			       GSocketAddress *address,
+			       GSocketType type,
+			       const char *protocol,
+			       GError **error)
+{
+  GSocketFamily family;
   GSocket *socket;
-  GSocketConnection *connection;
 
-  g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
+  if (!check_listener (listener, error))
+    return FALSE;
+
+  family = g_socket_address_get_family (address);
+  socket = g_socket_new (family, type, protocol, error);
+  if (socket == NULL)
+    return FALSE;
+
+  if (!g_socket_bind (socket, address, error) ||
+      !g_socket_listen (socket, error) ||
+      !g_socket_listener_add_socket (listener, socket, error))
+    {
+      g_object_unref (socket);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+g_socket_listener_add_inet_port (GSocketListener *listener,
+				 int port,
+				 GError **error)
+{
+  GSocketAddress *address4, *address6;
+  GInetAddress *inet_address;
+  gboolean res;
+
+  if (!check_listener (listener, error))
+    return FALSE;
+
+  inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
+  address4 = g_inet_socket_address_new (inet_address, port);
+  g_object_unref (inet_address);
+
+  inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
+  address6 = g_inet_socket_address_new (inet_address, port);
+  g_object_unref (inet_address);
+
+  if (!g_socket_listener_add_address (listener,
+				      address6,
+				      G_SOCKET_TYPE_STREAM,
+				      NULL,
+				      NULL))
+    {
+      /* Failed, to create ipv6, socket, just use ipv4,
+	 return any error */
+      res = g_socket_listener_add_address (listener,
+					   address4,
+					   G_SOCKET_TYPE_STREAM,
+					   NULL,
+					   error);
+    }
+  else
+    {
+      /* Succeeded with ipv6, also try ipv4 in case its ipv6 only,
+	 but ignore errors here */
+      res = TRUE;
+      g_socket_listener_add_address (listener,
+				     address4,
+				     G_SOCKET_TYPE_STREAM,
+				     NULL,
+				     NULL);
+    }
+
+  g_object_unref (address4);
+  g_object_unref (address6);
+
+  return res;
+}
+
+static GList *
+add_sources (GSocketListener *listener,
+	     GSocketSourceFunc callback,
+	     gpointer callback_data,
+	     GCancellable *cancellable,
+	     GMainContext *context)
+{
+  GSocket *socket;
+  GSource *source;
+  GList *sources;
+  int i;
 
-  if (listener->priv->error)
+  sources = NULL;
+  for (i = 0; i < listener->priv->sockets->len; i++)
     {
-      if (error)
-        *error = g_error_copy (listener->priv->error);
+      socket = listener->priv->sockets->pdata[i];
+
+      source = g_socket_create_source (socket, G_IO_IN, cancellable);
+      g_source_set_callback (source,
+                             (GSourceFunc) callback,
+                             callback_data, NULL);
+      g_source_attach (source, context);
+
+      sources = g_list_prepend (sources, source);
+    }
+
+  return sources;
+}
+
+static void
+free_sources (GList *sources)
+{
+  GSource *source;
+  while (sources != NULL)
+    {
+      source = sources->data;
+      sources = g_list_delete_link (sources, sources);
+      g_source_destroy (source);
+      g_source_unref (source);
+    }
+}
+
+struct AcceptData {
+  GMainLoop *loop;
+  GSocket *socket;
+};
+
+static gboolean
+accept_callback (GSocket *socket,
+		 GIOCondition condition,
+		 gpointer user_data)
+{
+  struct AcceptData *data = user_data;
+
+  data->socket = socket;
+  g_main_loop_quit (data->loop);
+
+  return TRUE;
+}
+
+GSocket *
+g_socket_listener_accept_socket (GSocketListener  *listener,
+				 GCancellable     *cancellable,
+				 GSocket         **source,
+				 GError          **error)
+{
+  GSocket *accept_socket, *socket;
+
+  g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
+
+  if (!check_listener (listener, error))
+    return NULL;
 
-      return NULL;
+  if (listener->priv->sockets->len == 1)
+    {
+      accept_socket = listener->priv->sockets->pdata[0];
+      if (!g_socket_condition_wait (accept_socket, G_IO_IN,
+				    cancellable, error))
+	return NULL;
+    }
+  else
+    {
+      GList *sources;
+      struct AcceptData data;
+      GMainLoop *loop;
+
+      if (listener->priv->main_context == NULL)
+	listener->priv->main_context = g_main_context_new ();
+
+      loop = g_main_loop_new (listener->priv->main_context, FALSE);
+      data.loop = loop;
+      sources = add_sources (listener,
+			     accept_callback,
+			     &data,
+			     cancellable,
+			     listener->priv->main_context);
+      g_main_loop_run (loop);
+      accept_socket = data.socket;
+      free_sources (sources);
+      g_main_loop_unref (loop);
     }
 
-  if (!g_socket_condition_wait (listener->priv->socket, G_IO_IN,
-                                cancellable, error))
+  if (!(socket = g_socket_accept (accept_socket, error)))
     return NULL;
 
-  if (!(socket = g_socket_accept (listener->priv->socket, error)))
+  if (source)
+    *source = accept_socket;
+
+  return socket;
+}
+
+GSocketConnection *
+g_socket_listener_accept (GSocketListener  *listener,
+			  GCancellable     *cancellable,
+			  GError          **error)
+{
+  GSocketConnection *connection;
+  GSocket *socket;
+
+  socket = g_socket_listener_accept_socket (listener,
+					    cancellable,
+					    NULL,
+					    error);
+  if (socket == NULL)
     return NULL;
 
   connection = g_socket_connection_factory_create_connection (socket);
-
   g_object_unref (socket);
 
   return connection;
 }
 
+struct AcceptAsyncData {
+  GSimpleAsyncResult *simple;
+  GCancellable *cancellable;
+  GList *sources;
+};
+
 static gboolean
-g_socket_listener_accept_ready (GSocket *socket,
-                                GIOCondition     condition,
-				GSocketListener *listener)
+accept_ready (GSocket *accept_socket,
+	      GIOCondition condition,
+	      gpointer _data)
 {
-  GSimpleAsyncResult *simple;
+  struct AcceptAsyncData *data = _data;
   GError *error = NULL;
 
-  simple = listener->priv->result;
-  listener->priv->result = NULL;
-
-  if (!g_cancellable_set_error_if_cancelled (listener->priv->cancellable,
+  if (!g_cancellable_set_error_if_cancelled (data->cancellable,
                                              &error))
     {
       GSocket *socket;
 
-      socket = g_socket_accept (listener->priv->socket, &error);
-
+      socket = g_socket_accept (accept_socket, &error);
       if (socket)
-        {
-          GSocketConnection *connection;
-
-	  connection = g_socket_connection_factory_create_connection (socket);
-
-          g_simple_async_result_set_op_res_gpointer (simple, connection,
-                                                     g_object_unref);
-          g_object_unref (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);
+	}
     }
 
   if (error)
     {
-      g_simple_async_result_set_from_error (simple, error);
+      g_simple_async_result_set_from_error (data->simple, error);
       g_error_free (error);
     }
 
-  if (listener->priv->cancellable)
-    {
-      g_object_unref (listener->priv->cancellable);
-      listener->priv->cancellable = NULL;
-    }
-
-  if (listener->priv->from_mainloop)
-    g_simple_async_result_complete (simple);
-  else
-    g_simple_async_result_complete_in_idle (simple);
-
-  g_object_unref (simple);
+  g_simple_async_result_complete_in_idle (data->simple);
+  g_object_unref (data->simple);
+  free_sources (data->sources);
+  g_free (data);
 
   return FALSE;
 }
 
+
 void
-g_socket_listener_accept_async (GSocketListener     *listener,
-                                GCancellable        *cancellable,
-                                GAsyncReadyCallback  callback,
-                                gpointer             user_data)
+g_socket_listener_accept_socket_async (GSocketListener      *listener,
+				       GCancellable         *cancellable,
+				       GAsyncReadyCallback   callback,
+				       gpointer              user_data)
 {
-  listener->priv->result =
-    g_simple_async_result_new (G_OBJECT (listener), callback, user_data,
-                               g_socket_listener_accept_async);
-
-  if (cancellable)
-    g_object_ref (cancellable);
-  listener->priv->cancellable = cancellable;
-
-  if (!g_socket_condition_check (listener->priv->socket, G_IO_IN))
-    {
-      GSource *source;
-
-      listener->priv->from_mainloop = TRUE;
-      source = g_socket_create_source (listener->priv->socket,
-                                       G_IO_IN, cancellable);
+  struct AcceptAsyncData *data;
+  GError *error = NULL;
 
-      g_source_set_callback (source,
-                             (GSourceFunc) g_socket_listener_accept_ready,
-                             g_object_ref (listener), g_object_unref);
-      g_source_attach (source, NULL);
-      g_source_unref (source);
-    }
-  else
+  if (!check_listener (listener, &error))
     {
-      listener->priv->from_mainloop = FALSE;
-      g_socket_listener_accept_ready (listener->priv->socket, G_IO_IN, listener);
+      g_simple_async_report_gerror_in_idle (G_OBJECT (listener),
+					    callback, user_data,
+					    error);
+      g_error_free (error);
+      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,
+			       NULL);
 }
 
-GSocketConnection *
-g_socket_listener_accept_finish (GSocketListener  *server,
-                               GAsyncResult   *result,
-                               GError        **error)
+GSocket *
+g_socket_listener_accept_socket_finish (GSocketListener      *listener,
+					GAsyncResult         *result,
+					GSocket             **source,
+					GError              **error)
 {
-  GSocketConnection *connection;
+  GSocket *socket;
   GSimpleAsyncResult *simple;
 
-  g_return_val_if_fail (G_IS_SOCKET_LISTENER (server), FALSE);
+  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_async);
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_listener_accept_socket_async);
 
-  connection = g_simple_async_result_get_op_res_gpointer (simple);
+  socket = g_simple_async_result_get_op_res_gpointer (simple);
 
-  return g_object_ref (connection);
+  if (source)
+    *source = g_object_ref (g_object_get_data (G_OBJECT (simple), "accept-socket"));
+
+  return g_object_ref (socket);
 }
 
 void
-g_socket_listener_close (GSocketListener *server)
+g_socket_listener_accept_async (GSocketListener     *listener,
+                                GCancellable        *cancellable,
+                                GAsyncReadyCallback  callback,
+                                gpointer             user_data)
+{
+  g_socket_listener_accept_socket_async (listener,
+					 cancellable,
+					 callback,
+					 user_data);
+}
+
+GSocketConnection *
+g_socket_listener_accept_finish (GSocketListener  *listener,
+				 GAsyncResult   *result,
+				 GError        **error)
 {
-  g_return_if_fail (G_IS_SOCKET_LISTENER (server));
+  GSocket *socket;
+  GSocketConnection *connection;
+
+  socket = g_socket_listener_accept_socket_finish (listener,
+						   result,
+						   NULL,
+						   error);
+  if (socket == NULL)
+    return NULL;
+
+  connection = g_socket_connection_factory_create_connection (socket);
+  g_object_unref (socket);
+  return connection;
+}
+
+void
+g_socket_listener_close (GSocketListener *listener)
+{
+  GSocket *socket;
+  int i;
+
+  g_return_if_fail (G_IS_SOCKET_LISTENER (listener));
+
+  if (listener->priv->closed)
+    return;
+
+  for (i = 0; i < listener->priv->sockets->len; i++)
+    {
+      socket = listener->priv->sockets->pdata[i];
+      g_socket_close (socket, NULL);
+    }
+  listener->priv->closed = TRUE;
 }
diff --git a/gio/gsocketlistener.h b/gio/gsocketlistener.h
index dfa1b1a..6278bab 100644
--- a/gio/gsocketlistener.h
+++ b/gio/gsocketlistener.h
@@ -46,8 +46,6 @@ struct _GSocketListenerClass
 {
   GObjectClass parent_class;
 
-  GSocket           * (* socket_factory)     (GSocketListener  *listener,
-                                              GError          **error);
   gpointer padding[6];
 };
 
@@ -59,23 +57,48 @@ struct _GSocketListener
 
 GType                   g_socket_listener_get_type                      (void);
 
-GSocketListener *       g_socket_listener_new                           (GSocketAddress       *address,
+GSocketListener *       g_socket_listener_new                           (void);
+
+gboolean                g_socket_listener_add_socket                    (GSocketListener     *listener,
+                                                                         GSocket             *socket,
+									 GError             **error);
+gboolean                g_socket_listener_add_address                   (GSocketListener      *listener,
+                                                                         GSocketAddress      *address,
+									 GSocketType          type,
+									 const char          *protocol,
+									 GError             **error);
+gboolean                g_socket_listener_add_inet_port                 (GSocketListener      *listener,
+                                                                         int                  port,
+									 GError             **error);
+
+GSocket *               g_socket_listener_accept_socket                 (GSocketListener      *listener,
+                                                                         GCancellable         *cancellable,
+									 GSocket             **source,
                                                                          GError              **error);
+void                    g_socket_listener_accept_socket_async           (GSocketListener      *listener,
+                                                                         GCancellable         *cancellable,
+                                                                         GAsyncReadyCallback   callback,
+                                                                         gpointer              user_data);
+GSocket *               g_socket_listener_accept_socket_finish          (GSocketListener      *listener,
+                                                                         GAsyncResult         *result,
+									 GSocket             **source,
+                                                                         GError              **error);
+
 
-GSocketConnection *     g_socket_listener_accept                        (GSocketListener      *server,
+GSocketConnection *     g_socket_listener_accept                        (GSocketListener      *listener,
                                                                          GCancellable         *cancellable,
                                                                          GError              **error);
 
-void                    g_socket_listener_accept_async                  (GSocketListener      *server,
+void                    g_socket_listener_accept_async                  (GSocketListener      *listener,
                                                                          GCancellable         *cancellable,
                                                                          GAsyncReadyCallback   callback,
                                                                          gpointer              user_data);
 
-GSocketConnection *     g_socket_listener_accept_finish                 (GSocketListener      *server,
+GSocketConnection *     g_socket_listener_accept_finish                 (GSocketListener      *listener,
                                                                          GAsyncResult         *result,
                                                                          GError              **error);
 
-void                    g_socket_listener_close                         (GSocketListener      *server);
+void                    g_socket_listener_close                         (GSocketListener      *listener);
 
 G_END_DECLS
 
diff --git a/gio/gtcplistener.c b/gio/gtcplistener.c
deleted file mode 100644
index cc0ef93..0000000
--- a/gio/gtcplistener.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright © 2009 Codethink Limited
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2 of the licence or (at
- * your option) any later version.
- *
- * See the included COPYING file for more information.
- *
- * Authors: Ryan Lortie <desrt desrt ca>
- */
-
-#include "gtcplistener.h"
-
-#include <gio/ginetsocketaddress.h>
-#include <gio/ginetaddress.h>
-
-#include "gtcpconnection.h"
-
-enum
-{
-  PROP_NONE,
-  PROP_PORT,
-  PROP_ADDRESS
-};
-
-struct _GTcpListenerPrivate
-{
-  GInetAddress *address;
-  guint16 port;
-};
-
-G_DEFINE_TYPE (GTcpListener, g_tcp_listener, G_TYPE_SOCKET_LISTENER);
-
-static GSocket *
-g_tcp_listener_socket_factory (GSocketListener  *listener,
-                               GError          **error)
-{
-  GTcpListener *tcp_listener = G_TCP_LISTENER (listener);
-  GSocketAddress *sockaddr;
-  GInetAddress *address;
-  GSocket *socket;
-
-  if (tcp_listener->priv->address)
-    /* address was explicitly given */
-    {
-      GSocketFamily family;
-
-      family = g_inet_address_get_family (tcp_listener->priv->address);
-      socket = g_socket_new (family, G_SOCKET_TYPE_STREAM, NULL, error);
-      address = g_object_ref (tcp_listener->priv->address);
-
-      if (family == G_SOCKET_FAMILY_IPV6)
-        /* XXX do ipv6-only-socket ioctl */;
-    }
-
-  else
-    {
-      /* try to get a hybrid ipv6/ipv4 socket first */
-      socket = g_socket_new (G_SOCKET_FAMILY_IPV6,
-                             G_SOCKET_TYPE_STREAM,
-			     NULL, NULL);
-
-      if (socket != NULL)
-        /* we can do ipv6, so bind to :: */
-        address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
-
-      else
-        /* no ipv6. bind to 0.0.0.0 */
-        {
-          socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
-                                 G_SOCKET_TYPE_STREAM,
-				 NULL, error);
-          address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
-        }
-    }
-
-  if (socket == NULL)
-    return NULL;
-
-  g_socket_set_reuse_address (socket, TRUE);
-
-  sockaddr = g_inet_socket_address_new (address, tcp_listener->priv->port);
-
-  if (!g_socket_bind (socket, sockaddr, error))
-    {
-      g_object_unref (socket);
-      socket = NULL;
-      goto err;
-    }
-
-  if (!g_socket_listen (socket, error))
-    {
-      g_object_unref (socket);
-      socket = NULL;
-    }
-
- err:
-  g_object_unref (sockaddr);
-  g_object_unref (address);
-
-  return socket;
-}
-
-static void
-g_tcp_listener_set_property (GObject *object, guint prop_id,
-                             const GValue *value, GParamSpec *pspec)
-{
-  GTcpListener *listener = G_TCP_LISTENER (object);
-
-  switch (prop_id)
-    {
-     case PROP_PORT:
-      g_assert (listener->priv->port == 0);
-      listener->priv->port = g_value_get_uint (value);
-      break;
-
-     case PROP_ADDRESS:
-      g_assert (listener->priv->address == NULL);
-      listener->priv->address = g_value_dup_object (value);
-      break;
-
-     default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
-}
-
-static void
-g_tcp_listener_get_property (GObject *object, guint prop_id,
-                             GValue *value, GParamSpec *pspec)
-{
-  GTcpListener *listener = G_TCP_LISTENER (object);
-
-  switch (prop_id)
-    {
-     case PROP_PORT:
-      g_value_set_uint (value, listener->priv->port);
-      break;
-
-     case PROP_ADDRESS:
-      g_value_set_object (value, listener->priv->address);
-      break;
-
-     default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
-}
-
-static void
-g_tcp_listener_init (GTcpListener *listener)
-{
-  listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener,
-                                                G_TYPE_TCP_LISTENER,
-                                                GTcpListenerPrivate);
-}
-
-static void
-g_tcp_listener_class_init (GTcpListenerClass *class)
-{
-  GSocketListenerClass *listener_class = G_SOCKET_LISTENER_CLASS (class);
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-  g_type_class_add_private (class, sizeof (GTcpListenerPrivate));
-
-  listener_class->socket_factory = g_tcp_listener_socket_factory;
-  object_class->set_property = g_tcp_listener_set_property;
-  object_class->get_property = g_tcp_listener_get_property;
-
-  g_object_class_install_property (object_class, PROP_PORT,
-    g_param_spec_uint ("port", "port number",
-                       "the TCP port number to bind (0 for any)",
-                       0, G_MAXUINT16, 0, G_PARAM_READWRITE |
-                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
-                       G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
-  g_object_class_install_property (object_class, PROP_ADDRESS,
-    g_param_spec_object ("address", "IP address",
-                         "the local address to bind (NULL for all)",
-                         G_TYPE_INET_ADDRESS, G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
-                         G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-}
-
-GSocketListener *
-g_tcp_listener_new (guint16 port)
-{
-  return g_object_new (G_TYPE_TCP_LISTENER, "port", port, NULL);
-}
diff --git a/gio/gtcplistener.h b/gio/gtcplistener.h
deleted file mode 100644
index 6404ce7..0000000
--- a/gio/gtcplistener.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright © 2009 Codethink Limited
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2 of the licence or (at
- * your option) any later version.
- *
- * See the included COPYING file for more information.
- *
- * Authors: Ryan Lortie <desrt desrt ca>
- */
-
-#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
-#error "Only <gio/gio.h> can be included directly."
-#endif
-
-#ifndef _gtcplistener_h_
-#define _gtcplistener_h_
-
-#include <gio/gsocketlistener.h>
-
-G_BEGIN_DECLS
-
-#define G_TYPE_TCP_LISTENER                                 (g_tcp_listener_get_type ())
-#define G_TCP_LISTENER(inst)                                (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
-                                                             G_TYPE_TCP_LISTENER, GTcpListener))
-#define G_TCP_LISTENER_CLASS(class)                         (G_TYPE_CHECK_CLASS_CAST ((class),                       \
-                                                             G_TYPE_TCP_LISTENER, GTcpListenerClass))
-#define G_IS_TCP_LISTENER(inst)                             (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
-                                                             G_TYPE_TCP_LISTENER))
-#define G_IS_TCP_LISTENER_CLASS(class)                      (G_TYPE_CHECK_CLASS_TYPE ((class),                       \
-                                                             G_TYPE_TCP_LISTENER))
-#define G_TCP_LISTENER_GET_CLASS(inst)                      (G_TYPE_INSTANCE_GET_CLASS ((inst),                      \
-                                                             G_TYPE_TCP_LISTENER, GTcpListenerClass))
-
-typedef struct _GTcpListenerPrivate                         GTcpListenerPrivate;
-typedef struct _GTcpListenerClass                           GTcpListenerClass;
-typedef struct _GTcpListener                                GTcpListener;
-
-struct _GTcpListenerClass
-{
-  GSocketListenerClass parent_class;
-};
-
-struct _GTcpListener
-{
-  GSocketListener parent_instance;
-  GTcpListenerPrivate *priv;
-};
-
-GType                   g_tcp_listener_get_type                         (void);
-GSocketListener *       g_tcp_listener_new                              (guint16 port);
-
-G_END_DECLS
-
-#endif /* _gtcplistener_h_ */
diff --git a/gio/gunixlistener.c b/gio/gunixlistener.c
deleted file mode 100644
index 92678d4..0000000
--- a/gio/gunixlistener.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright © 2009 Codethink Limited
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2 of the licence or (at
- * your option) any later version.
- *
- * See the included COPYING file for more information.
- *
- * Authors: Ryan Lortie <desrt desrt ca>
- */
-
-#include "gunixlistener.h"
-
-#include <gio/gunixsocketaddress.h>
-
-#include "gunixconnection.h"
-
-enum
-{
-  PROP_NONE,
-  PROP_PATH,
-};
-
-struct _GUnixListenerPrivate
-{
-  gchar *path;
-};
-
-G_DEFINE_TYPE (GUnixListener, g_unix_listener, G_TYPE_SOCKET_LISTENER);
-
-static GSocket *
-g_unix_listener_socket_factory (GSocketListener  *listener,
-                                GError          **error)
-{
-  GUnixListener *unix_listener = G_UNIX_LISTENER (listener);
-  GSocketAddress *sockaddr;
-  GSocket *socket;
-
-  socket = g_socket_new (G_SOCKET_FAMILY_UNIX,
-                         G_SOCKET_TYPE_STREAM,
-			 NULL, error);
-  if (socket == NULL)
-    return NULL;
-
-  sockaddr = g_unix_socket_address_new (unix_listener->priv->path);
-
-  /* XXX fix */
-  g_socket_bind (socket, sockaddr, NULL);
-  g_socket_listen (socket, NULL);
-
-  g_object_unref (sockaddr);
-
-  return socket;
-}
-
-static void
-g_unix_listener_set_property (GObject *object, guint prop_id,
-                             const GValue *value, GParamSpec *pspec)
-{
-  GUnixListener *listener = G_UNIX_LISTENER (object);
-
-  switch (prop_id)
-    {
-     case PROP_PATH:
-      g_assert (listener->priv->path == NULL);
-      listener->priv->path = g_value_dup_string (value);
-      break;
-
-     default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
-}
-
-static void
-g_unix_listener_get_property (GObject *object, guint prop_id,
-                             GValue *value, GParamSpec *pspec)
-{
-  GUnixListener *listener = G_UNIX_LISTENER (object);
-
-  switch (prop_id)
-    {
-     case PROP_PATH:
-      g_value_set_string (value, listener->priv->path);
-      break;
-
-     default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
-}
-
-static void
-g_unix_listener_init (GUnixListener *listener)
-{
-  listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener,
-                                                G_TYPE_UNIX_LISTENER,
-                                                GUnixListenerPrivate);
-}
-
-static void
-g_unix_listener_class_init (GUnixListenerClass *class)
-{
-  GSocketListenerClass *listener_class = G_SOCKET_LISTENER_CLASS (class);
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-  g_type_class_add_private (class, sizeof (GUnixListenerPrivate));
-
-  listener_class->socket_factory = g_unix_listener_socket_factory;
-  object_class->set_property = g_unix_listener_set_property;
-  object_class->get_property = g_unix_listener_get_property;
-
-  g_object_class_install_property (object_class, PROP_PATH,
-    g_param_spec_string ("path", "socket path",
-                         "the filesystem path to bind to",
-                         NULL, G_PARAM_READWRITE |
-                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
-                         G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-}
-
-GSocketListener *
-g_unix_listener_new (const gchar *path)
-{
-  return g_object_new (G_TYPE_UNIX_LISTENER, "path", path, NULL);
-}
diff --git a/gio/gunixlistener.h b/gio/gunixlistener.h
deleted file mode 100644
index 819137b..0000000
--- a/gio/gunixlistener.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright © 2009 Codethink Limited
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2 of the licence or (at
- * your option) any later version.
- *
- * See the included COPYING file for more information.
- *
- * Authors: Ryan Lortie <desrt desrt ca>
- */
-
-#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
-#error "Only <gio/gio.h> can be included directly."
-#endif
-
-#ifndef _gunixlistener_h_
-#define _gunixlistener_h_
-
-#include <gio/gsocketlistener.h>
-
-G_BEGIN_DECLS
-
-#define G_TYPE_UNIX_LISTENER                                (g_unix_listener_get_type ())
-#define G_UNIX_LISTENER(inst)                               (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
-                                                             G_TYPE_UNIX_LISTENER, GUnixListener))
-#define G_UNIX_LISTENER_CLASS(class)                        (G_TYPE_CHECK_CLASS_CAST ((class),                       \
-                                                             G_TYPE_UNIX_LISTENER, GUnixListenerClass))
-#define G_IS_UNIX_LISTENER(inst)                            (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
-                                                             G_TYPE_UNIX_LISTENER))
-#define G_IS_UNIX_LISTENER_CLASS(class)                     (G_TYPE_CHECK_CLASS_TYPE ((class),                       \
-                                                             G_TYPE_UNIX_LISTENER))
-#define G_UNIX_LISTENER_GET_CLASS(inst)                     (G_TYPE_INSTANCE_GET_CLASS ((inst),                      \
-                                                             G_TYPE_UNIX_LISTENER, GUnixListenerClass))
-
-typedef struct _GUnixListenerPrivate                        GUnixListenerPrivate;
-typedef struct _GUnixListenerClass                          GUnixListenerClass;
-typedef struct _GUnixListener                               GUnixListener;
-
-struct _GUnixListenerClass
-{
-  GSocketListenerClass parent_class;
-};
-
-struct _GUnixListener
-{
-  GSocketListener parent_instance;
-  GUnixListenerPrivate *priv;
-};
-
-GType                   g_unix_listener_get_type                        (void);
-GSocketListener *       g_unix_listener_new                             (const gchar *path);
-
-G_END_DECLS
-
-#endif /* _gunixlistener_h_ */



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