[gnio/connection-factory] Add start/stop to GSocketService



commit ab0da24fe66b66b01530a5b214745ece50fa5369
Author: Alexander Larsson <alexl redhat com>
Date:   Mon May 11 21:24:34 2009 +0200

    Add start/stop to GSocketService
    
    This lets users and subclasses stop processing of the accept
    sockets.
---
 gio/gsocketservice.c |   97 ++++++++++++++++++++++++++++++++++++++++++++------
 gio/gsocketservice.h |    8 +++-
 2 files changed, 92 insertions(+), 13 deletions(-)

diff --git a/gio/gsocketservice.c b/gio/gsocketservice.c
index 09bcf0b..f4f20d8 100644
--- a/gio/gsocketservice.c
+++ b/gio/gsocketservice.c
@@ -46,9 +46,12 @@ static guint g_socket_service_incoming_signal;
 
 G_DEFINE_TYPE (GSocketService, g_socket_service, G_TYPE_SOCKET_LISTENER);
 
+G_LOCK_DEFINE_STATIC(active);
+
 struct _GSocketServicePrivate
 {
   GCancellable *cancellable;
+  guint active : 1;
   guint outstanding_accept : 1;
 };
 
@@ -71,6 +74,7 @@ g_socket_service_init (GSocketService *service)
 					       G_TYPE_SOCKET_SERVICE,
 					       GSocketServicePrivate);
   service->priv->cancellable = g_cancellable_new ();
+  service->priv->active = TRUE;
 }
 
 static void
@@ -85,18 +89,84 @@ g_socket_service_finalize (GObject *object)
 }
 
 static void
+do_accept (GSocketService  *service)
+{
+  g_socket_listener_accept_async (G_SOCKET_LISTENER (service),
+				  service->priv->cancellable,
+				  g_socket_service_ready, NULL);
+  service->priv->outstanding_accept = TRUE;
+}
+
+static void
 g_socket_service_changed (GSocketListener *listener)
 {
   GSocketService  *service = G_SOCKET_SERVICE (listener);
 
-  if (service->priv->outstanding_accept)
-    g_cancellable_cancel (service->priv->cancellable);
-  else
-    g_socket_listener_accept_async (listener, service->priv->cancellable,
-				    g_socket_service_ready, NULL);
-  service->priv->outstanding_accept = TRUE;
+  G_LOCK (active);
+
+  if (service->priv->active)
+    {
+      if (service->priv->outstanding_accept)
+	g_cancellable_cancel (service->priv->cancellable);
+      else
+	{
+	  g_socket_listener_accept_async (listener, service->priv->cancellable,
+					  g_socket_service_ready, NULL);
+	  service->priv->outstanding_accept = TRUE;
+	}
+    }
+
+  G_UNLOCK (active);
+}
+
+gboolean
+g_socket_service_is_active (GSocketService *service)
+{
+  gboolean active;
+
+  G_LOCK (active);
+  active = service->priv->active;
+  G_UNLOCK (active);
+  return active;
 }
 
+void
+g_socket_service_start (GSocketService *service)
+{
+  g_print ("g_socket_service_start\n");
+  G_LOCK (active);
+
+  if (!service->priv->active)
+    {
+      service->priv->active = TRUE;
+
+      if (service->priv->outstanding_accept)
+	g_cancellable_cancel (service->priv->cancellable);
+      else
+	do_accept (service);
+    }
+
+  G_UNLOCK (active);
+}
+
+void
+g_socket_service_stop (GSocketService  *service)
+{
+  g_print ("g_socket_service_stop\n");
+  G_LOCK (active);
+
+  if (service->priv->active)
+    {
+      service->priv->active = FALSE;
+
+      if (service->priv->outstanding_accept)
+	g_cancellable_cancel (service->priv->cancellable);
+    }
+
+  G_UNLOCK (active);
+}
+
+
 static gboolean
 g_socket_service_incoming (GSocketService    *service,
                            GSocketConnection *connection,
@@ -157,9 +227,7 @@ g_socket_service_ready (GObject      *object,
   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))
-	g_cancellable_reset (service->priv->cancellable);
-      else
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
 	g_warning ("fail: %s", error->message);
       g_error_free (error);
     }
@@ -169,9 +237,16 @@ g_socket_service_ready (GObject      *object,
       g_object_unref (connection);
     }
 
+  G_LOCK (active);
+
+  g_cancellable_reset (service->priv->cancellable);
+
   /* requeue */
-  g_socket_listener_accept_async (listener, service->priv->cancellable,
-                                  g_socket_service_ready, NULL);
+  service->priv->outstanding_accept = FALSE;
+  if (service->priv->active)
+    do_accept (service);
+
+  G_UNLOCK (active);
 }
 
 
diff --git a/gio/gsocketservice.h b/gio/gsocketservice.h
index ff209b2..8836904 100644
--- a/gio/gsocketservice.h
+++ b/gio/gsocketservice.h
@@ -54,9 +54,13 @@ struct _GSocketService
   GSocketServicePrivate *priv;
 };
 
-GType                   g_socket_service_get_type                       (void);
+GType           g_socket_service_get_type  (void);
+
+GSocketService *g_socket_service_new       (void);
+void            g_socket_service_start     (GSocketService *service);
+void            g_socket_service_stop      (GSocketService *service);
+gboolean        g_socket_service_is_active (GSocketService *service);
 
-GSocketService *        g_socket_service_new                            (void);
 
 G_END_DECLS
 



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