[gnio/connection-factory] Make GSocketService inherit from GSocketListener
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnio/connection-factory] Make GSocketService inherit from GSocketListener
- Date: Sat, 9 May 2009 17:18:05 -0400 (EDT)
commit 3e9586b11f3c033dec452fe07366a5404320bc65
Author: Alexander Larsson <alexl redhat com>
Date: Sat May 9 23:15:38 2009 +0200
Make GSocketService inherit from GSocketListener
---
examples/server.c | 7 +--
gio/gsocketlistener.c | 12 +++-
gio/gsocketlistener.h | 3 +
gio/gsocketservice.c | 131 ++++++++++++++++++++++--------------------
gio/gsocketservice.h | 9 +--
gio/gthreadedsocketservice.c | 14 ++--
gio/gthreadedsocketservice.h | 2 +-
7 files changed, 92 insertions(+), 86 deletions(-)
diff --git a/examples/server.c b/examples/server.c
index 51d4566..0833788 100644
--- a/examples/server.c
+++ b/examples/server.c
@@ -44,7 +44,6 @@ main (int argc, char *argv[])
GSocketService *service;
GOptionContext *context;
GError *error = NULL;
- GSocketListener *listener;
g_type_init ();
g_thread_init (NULL);
@@ -59,8 +58,7 @@ main (int argc, char *argv[])
service = g_threaded_socket_service_new ();
- listener = g_socket_listener_new ();
- if (!g_socket_listener_add_inet_port (listener,
+ if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service),
port,
&error))
{
@@ -68,9 +66,6 @@ main (int argc, char *argv[])
return 1;
}
- g_socket_service_add_listener (service, listener);
- g_object_unref (listener);
-
g_print ("Echo service listening on port %d\n", port);
g_signal_connect (service, "run", G_CALLBACK (handler), NULL);
diff --git a/gio/gsocketlistener.c b/gio/gsocketlistener.c
index 2df057c..8ebdc04 100644
--- a/gio/gsocketlistener.c
+++ b/gio/gsocketlistener.c
@@ -140,6 +140,9 @@ g_socket_listener_add_address (GSocketListener *listener,
return FALSE;
}
+ if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
+ G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
+
return TRUE;
}
@@ -442,16 +445,17 @@ g_socket_listener_accept_async (GSocketListener *listener,
}
GSocketConnection *
-g_socket_listener_accept_finish (GSocketListener *listener,
- GAsyncResult *result,
- GError **error)
+g_socket_listener_accept_finish (GSocketListener *listener,
+ GAsyncResult *result,
+ GSocket **source,
+ GError **error)
{
GSocket *socket;
GSocketConnection *connection;
socket = g_socket_listener_accept_socket_finish (listener,
result,
- NULL,
+ source,
error);
if (socket == NULL)
return NULL;
diff --git a/gio/gsocketlistener.h b/gio/gsocketlistener.h
index 6278bab..c9f6e71 100644
--- a/gio/gsocketlistener.h
+++ b/gio/gsocketlistener.h
@@ -46,6 +46,8 @@ struct _GSocketListenerClass
{
GObjectClass parent_class;
+ void (* changed) (GSocketListener *listener);
+
gpointer padding[6];
};
@@ -96,6 +98,7 @@ void g_socket_listener_accept_async (GSocket
GSocketConnection * g_socket_listener_accept_finish (GSocketListener *listener,
GAsyncResult *result,
+ GSocket **source,
GError **error);
void g_socket_listener_close (GSocketListener *listener);
diff --git a/gio/gsocketservice.c b/gio/gsocketservice.c
index 1610dee..36ea813 100644
--- a/gio/gsocketservice.c
+++ b/gio/gsocketservice.c
@@ -38,17 +38,28 @@
#include "gsocketservice.h"
#include "gnio-marshal.h"
+#include <gio/gio.h>
#include "gsocketlistener.h"
#include "gsocketconnection.h"
static guint g_socket_service_incoming_signal;
-G_DEFINE_TYPE (GSocketService, g_socket_service, G_TYPE_OBJECT);
+G_DEFINE_TYPE (GSocketService, g_socket_service, G_TYPE_SOCKET_LISTENER);
+
+struct _GSocketServicePrivate
+{
+ GCancellable *cancellable;
+ gboolean active;
+};
+
+static void g_socket_service_ready (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data);
static gboolean
g_socket_service_real_incoming (GSocketService *service,
GSocketConnection *connection,
- GSocketListener *listener)
+ GSocket *source_socket)
{
return FALSE;
}
@@ -56,29 +67,65 @@ g_socket_service_real_incoming (GSocketService *service,
static void
g_socket_service_init (GSocketService *service)
{
+ service->priv = G_TYPE_INSTANCE_GET_PRIVATE (service,
+ G_TYPE_SOCKET_SERVICE,
+ GSocketServicePrivate);
+ service->priv->cancellable = g_cancellable_new ();
+}
+
+static void
+g_socket_service_finalize (GObject *object)
+{
+ GSocketService *service = G_SOCKET_SERVICE (object);
+
+ g_object_unref (service->priv->cancellable);
+
+ G_OBJECT_CLASS (g_socket_service_parent_class)
+ ->finalize (object);
}
static void
+g_socket_service_changed (GSocketListener *listener)
+{
+ GSocketService *service = G_SOCKET_SERVICE (listener);
+
+ if (service->priv->active)
+ g_cancellable_cancel (service->priv->cancellable);
+ else
+ g_socket_listener_accept_async (listener, service->priv->cancellable,
+ g_socket_service_ready, NULL);
+ service->priv->active = TRUE;
+}
+
+static gboolean
g_socket_service_incoming (GSocketService *service,
GSocketConnection *connection,
- GSocketListener *listener)
+ GSocket *source_socket)
{
gboolean result;
g_signal_emit (service, g_socket_service_incoming_signal,
- 0, connection, listener, &result);
+ 0, connection, source_socket, &result);
+ return result;
}
static void
g_socket_service_class_init (GSocketServiceClass *class)
{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ GSocketListenerClass *listener_class = G_SOCKET_LISTENER_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (GSocketServicePrivate));
+
+ gobject_class->finalize = g_socket_service_finalize;
+ listener_class->changed = g_socket_service_changed;
class->incoming = g_socket_service_real_incoming;
/**
* GSocketService::incoming:
* @service: the #GSocketService.
* @connection: a new #GSocketConnection object.
- * @listener: the #GSocketListener whence @connection originated.
+ * @source_socket: the #GSocket whence @connection was accepted.
* @returns: %TRUE if @connection has been handled.
*
* The ::incoming signal is emitted when a new incoming connection
@@ -93,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_LISTENER);
+ 2, G_TYPE_SOCKET_CONNECTION, G_TYPE_SOCKET);
}
static void
@@ -102,72 +149,32 @@ g_socket_service_ready (GObject *object,
gpointer user_data)
{
GSocketListener *listener = G_SOCKET_LISTENER (object);
- GSocketService *service = user_data;
+ GSocketService *service = G_SOCKET_SERVICE (object);
GSocketConnection *connection;
+ GSocket *source;
GError *error = NULL;
- connection = g_socket_listener_accept_finish (listener, result, &error);
+ connection = g_socket_listener_accept_finish (listener, result, &source, &error);
if (error)
- g_error ("fail: %s", error->message);
- g_socket_service_incoming (service, connection, listener);
- g_object_unref (connection);
+ {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_cancellable_reset (service->priv->cancellable);
+ else
+ g_warning ("fail: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ g_socket_service_incoming (service, connection, source);
+ g_object_unref (connection);
+ g_object_unref (source);
+ }
/* requeue */
g_socket_listener_accept_async (listener, NULL,
g_socket_service_ready, service);
}
-/**
- * g_socket_service_add_listener:
- * @service: a #GSocketService.
- * @listener: a newly created #GSocketListener.
- *
- * Adds a #GSocketListener to @service.
- *
- * A #GSocketService must have at least one #GSocketListener in order
- * to listen for incoming connections. Any number of listeners may be
- * added and connections are accepted from all of them.
- *
- * This call forms a mutual reference between @service and @listener
- * and keeps both alive. You can drop your own references to each of
- * them and connections will continue to be accepted.
- *
- * If you want to destroy a service, call g_socket_service_destroy()
- * on it. This is equivalent to removing all of the listeners.
- **/
-void
-g_socket_service_add_listener (GSocketService *service,
- GSocketListener *listener)
-{
- g_return_if_fail (G_IS_SOCKET_SERVICE (service));
- g_return_if_fail (G_IS_SOCKET_LISTENER (listener));
-
- g_socket_listener_accept_async (listener,
- NULL, //g_object_ref (service->cancellable),
- g_socket_service_ready,
- g_object_ref (service));
-}
-
-/**
- * g_socket_service_destroy:
- * @service: a #GSocketService.
- *
- * Requests cancellation of all accept requests on the listeners
- * associated with @service. It is likely that one or more mainloop
- * visits will be required before all requests are fully cancelled.
- *
- * If @service held the only reference on a given listener then that
- * listener will be freed and its associated socket will be closed.
- * If other references are held, then listener may be used elsewhere.
- *
- * This call does not drop the caller's reference on @service. You
- * will need to do that yourself with g_object_unref().
- **/
-void
-g_socket_service_destroy (GSocketService *service)
-{
- g_assert_not_reached ();
-}
/**
* g_socket_service_new:
diff --git a/gio/gsocketservice.h b/gio/gsocketservice.h
index 3eb97fd..cae3eef 100644
--- a/gio/gsocketservice.h
+++ b/gio/gsocketservice.h
@@ -40,26 +40,23 @@ typedef struct _GSocketService GSocketService;
struct _GSocketServiceClass
{
- GObjectClass parent_class;
+ GSocketListenerClass parent_class;
gboolean (* incoming) (GSocketService *service,
GSocketConnection *connection,
- GSocketListener *listener);
+ GSocket *source_socket);
gpointer padding[6];
};
struct _GSocketService
{
- GObject parent_instance;
+ GSocketListener parent_instance;
GSocketServicePrivate *priv;
};
GType g_socket_service_get_type (void);
GSocketService * g_socket_service_new (void);
-void g_socket_service_add_listener (GSocketService *service,
- GSocketListener *listener);
-void g_socket_service_destroy (GSocketService *service);
G_END_DECLS
diff --git a/gio/gthreadedsocketservice.c b/gio/gthreadedsocketservice.c
index 0d97712..bc85d1b 100644
--- a/gio/gthreadedsocketservice.c
+++ b/gio/gthreadedsocketservice.c
@@ -42,7 +42,7 @@ typedef struct
{
GThreadedSocketService *service;
GSocketConnection *connection;
- GSocketListener *listener;
+ GSocket *source_socket;
} GThreadedSocketServiceData;
static gpointer
@@ -52,27 +52,27 @@ 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->listener, &result);
+ 0, data->connection, data->source_socket, &result);
g_object_unref (data->service);
g_object_unref (data->connection);
- g_object_unref (data->listener);
+ g_object_unref (data->source_socket);
g_slice_free (GThreadedSocketServiceData, data);
-
+
return NULL;
}
static gboolean
g_threaded_socket_service_incoming (GSocketService *service,
GSocketConnection *connection,
- GSocketListener *listener)
+ GSocket *source_socket)
{
GThreadedSocketServiceData *data;
data = g_slice_new (GThreadedSocketServiceData);
data->service = g_object_ref (service);
data->connection = g_object_ref (connection);
- data->listener = g_object_ref (listener);
+ data->source_socket = g_object_ref (source_socket);
g_thread_create (g_threaded_socket_service_func, data, FALSE, NULL);
return FALSE;
@@ -109,7 +109,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_LISTENER);
+ 2, G_TYPE_SOCKET_CONNECTION, G_TYPE_SOCKET);
}
/**
diff --git a/gio/gthreadedsocketservice.h b/gio/gthreadedsocketservice.h
index d7b92da..d0fe165 100644
--- a/gio/gthreadedsocketservice.h
+++ b/gio/gthreadedsocketservice.h
@@ -47,7 +47,7 @@ struct _GThreadedSocketServiceClass
gboolean (* run) (GThreadedSocketService *service,
GSocketConnection *connection,
- GSocketListener *listener);
+ GSocket *source_socket);
};
struct _GThreadedSocketService
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]