[gnio] Convert GSocket to GInitable and update users
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnio] Convert GSocket to GInitable and update users
- Date: Wed, 6 May 2009 17:17:13 -0400 (EDT)
commit 12f26bcb477a20804d28a52f1461699325f7d5cf
Author: Alexander Larsson <alexl redhat com>
Date: Wed May 6 23:14:47 2009 +0200
Convert GSocket to GInitable and update users
This removes g_socket_has_error and instead introduces a GError in
the GSocket C constuctor helpers that are now switched to use
g_initable_new.
Also, all users are changed to comply with the API changes.
---
gio/gsocket.c | 115 ++++++++++++++++++++++++++++++++++++++------------
gio/gsocket.h | 8 ++--
gio/gsocketclient.c | 74 +++++++++++++++++---------------
gio/gsocketclient.h | 3 +-
gio/gtcpclient.c | 5 +-
gio/gtcplistener.c | 10 ++--
gio/gunixclient.c | 5 +-
gio/gunixlistener.c | 5 ++-
test/server.c | 4 +-
9 files changed, 149 insertions(+), 80 deletions(-)
diff --git a/gio/gsocket.c b/gio/gsocket.c
index d570210..3be1072 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -42,15 +42,21 @@
#include <gio/gcancellable.h>
#include <gio/gioenumtypes.h>
+#include <gio/ginitable.h>
#include "gsocketcontrol-private.h"
#include "gasynchelper.h"
#include "gnioerror.h"
#include "gnioenums.h"
#include <gio/gioerror.h>
+static void g_socket_initable_iface_init (GInitableIface *iface);
+static gboolean g_socket_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error);
-
-G_DEFINE_TYPE (GSocket, g_socket, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE (GSocket, g_socket, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ g_socket_initable_iface_init));
enum
{
@@ -77,6 +83,7 @@ struct _GSocketPrivate
GError *construct_error;
GSocketAddress *local_address;
GSocketAddress *remote_address;
+ guint inited : 1;
guint blocking : 1;
guint reuse_address : 1;
guint keepalive : 1;
@@ -172,17 +179,25 @@ static gboolean
check_socket (GSocket *socket,
GError **error)
{
+ if (!socket->priv->inited)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED,
+ _("Invalid socket, not initialized"));
+ return FALSE;
+ }
+
if (socket->priv->construct_error)
{
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Invalid socket, creation failed due to: %s"),
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED,
+ _("Invalid socket, initialization failed due to: %s"),
socket->priv->construct_error->message);
return FALSE;
}
+
if (socket->priv->closed)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("Socket is already closed"));
+ _("Socket is already closed"));
return FALSE;
}
return TRUE;
@@ -673,6 +688,12 @@ g_socket_class_init (GSocketClass *klass)
}
static void
+g_socket_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = g_socket_initable_init;
+}
+
+static void
g_socket_init (GSocket *socket)
{
socket->priv = G_TYPE_INSTANCE_GET_PRIVATE (socket, G_TYPE_SOCKET, GSocketPrivate);
@@ -689,18 +710,60 @@ g_socket_init (GSocket *socket)
#endif
}
+static gboolean
+g_socket_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GSocket *socket;
+
+ g_return_val_if_fail (G_IS_SOCKET (initable), FALSE);
+
+ socket = G_SOCKET (initable);
+
+ if (cancellable != NULL)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Cancellable initialization not supported"));
+ return FALSE;
+ }
+
+ socket->priv->inited = TRUE;
+
+ if (socket->priv->construct_error)
+ {
+ if (error)
+ *error = g_error_copy (socket->priv->construct_error);
+ return FALSE;
+ }
+
+
+ return TRUE;
+}
+
+
GSocket *
g_socket_new (GSocketFamily family,
GSocketType type,
- const char *protocol)
+ const char *protocol,
+ GError **error)
{
- return G_SOCKET (g_object_new (G_TYPE_SOCKET, "family", family, "type", type, "protocol", protocol, NULL));
+ return G_SOCKET (g_initable_new (G_TYPE_SOCKET,
+ NULL, error,
+ "family", family,
+ "type", type,
+ "protocol", protocol,
+ NULL));
}
GSocket *
-g_socket_new_from_fd (gint fd)
+g_socket_new_from_fd (gint fd,
+ GError **error)
{
- return G_SOCKET (g_object_new (G_TYPE_SOCKET, "fd", fd, NULL));
+ return G_SOCKET (g_initable_new (G_TYPE_SOCKET,
+ NULL, error,
+ "fd", fd,
+ NULL));
}
void
@@ -899,21 +962,6 @@ g_socket_get_remote_address (GSocket *socket,
}
gboolean
-g_socket_has_error (GSocket *socket,
- GError **error)
-{
- g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
-
- if (!socket->priv->construct_error)
- return FALSE;
-
- if (error)
- *error = g_error_copy (socket->priv->construct_error);
-
- return TRUE;
-}
-
-gboolean
g_socket_is_connected (GSocket *socket)
{
g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
@@ -1039,13 +1087,24 @@ g_socket_accept (GSocket *socket,
}
#endif
- new_socket = g_socket_new_from_fd (ret);
+ new_socket = g_socket_new_from_fd (ret, error);
+ if (new_socket)
+ {
+#ifdef G_OS_WIN32
+ /* We set blocking above, and new_from_fd can't read this on win32 */
+ new_socket->priv->blocking = TRUE;
+ new_socket->priv->blocking_mode_unknown = FALSE;
+#endif
+ }
+ else
+ {
#ifdef G_OS_WIN32
- /* We set blocking above, and new_from_fd can't read this on win32 */
- new_socket->priv->blocking = TRUE;
- new_socket->priv->blocking_mode_unknown = FALSE;
+ closesocket (ret);
+#else
+ close (ret);
#endif
+ }
return new_socket;
}
diff --git a/gio/gsocket.h b/gio/gsocket.h
index dd65b29..c604b37 100644
--- a/gio/gsocket.h
+++ b/gio/gsocket.h
@@ -91,8 +91,10 @@ typedef gboolean (*GSocketSourceFunc) (gpointer user_data,
GType g_socket_get_type (void);
GSocket * g_socket_new (GSocketFamily family,
GSocketType type,
- const char *protocol);
-GSocket * g_socket_new_from_fd (gint fd);
+ const char *protocol,
+ GError **error);
+GSocket * g_socket_new_from_fd (gint fd,
+ GError **error);
int g_socket_get_fd (GSocket *socket);
GSocketAddress * g_socket_get_local_address (GSocket *socket,
GError **error);
@@ -110,8 +112,6 @@ gboolean g_socket_get_keepalive (GSocket
gint g_socket_get_listen_backlog (GSocket *socket);
void g_socket_set_listen_backlog (GSocket *socket,
gint backlog);
-gboolean g_socket_has_error (GSocket *socket,
- GError **error);
gboolean g_socket_is_connected (GSocket *socket);
gboolean g_socket_bind (GSocket *socket,
GSocketAddress *address,
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index 559c8b3..2e9245c 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -33,10 +33,11 @@ G_DEFINE_TYPE (GSocketClient, g_socket_client, G_TYPE_OBJECT);
static GSocket *
g_socket_client_real_socket_factory (GSocketClient *client,
- GSocketAddress *address)
+ GSocketAddress *address,
+ GError **error)
{
return g_socket_new (g_socket_address_get_family (address),
- G_SOCKET_TYPE_STREAM, NULL);
+ G_SOCKET_TYPE_STREAM, NULL, error);
}
static void
@@ -62,6 +63,9 @@ g_socket_client_connect (GSocketClient *client,
class = G_SOCKET_CLIENT_GET_CLASS (client);
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return NULL;
+
enumerator = g_socket_connectable_enumerate (connectable);
while (!connection && !g_cancellable_is_cancelled (cancellable))
{
@@ -74,7 +78,6 @@ g_socket_client_connect (GSocketClient *client,
if (address == NULL)
{
g_assert (error == NULL || *error != NULL);
-
break;
}
@@ -82,14 +85,14 @@ g_socket_client_connect (GSocketClient *client,
if (error && *error)
g_clear_error (error);
- socket = class->socket_factory (client, address);
-
- if (g_cancellable_is_cancelled (cancellable))
- break;
-
- if (g_socket_connect (socket, address, error))
- connection = class->connection_factory (client, socket);
+ socket = class->socket_factory (client, address, error);
+ if (socket != NULL)
+ {
+ if (g_socket_connect (socket, address, error))
+ connection = class->connection_factory (client, socket);
+ }
+ g_object_unref (address);
g_object_unref (socket);
}
g_object_unref (enumerator);
@@ -146,19 +149,17 @@ static gboolean
g_socket_client_socket_callback (GSocketClientAsyncConnectData *data,
GIOCondition condition)
{
- if (condition & G_IO_OUT)
- /* socket is ready for writing = success. */
- ;
-
- else if (condition)
+ if (g_cancellable_set_error_if_cancelled (data->cancellable,
+ &data->last_error))
{
- if (!g_socket_has_error (data->current_socket, &data->last_error))
- {
- g_warning ("Failed to connect async, but socket didn't set error");
- g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Async connection failed and socket didn't set error");
- }
-
+ }
+ else if (condition & G_IO_OUT)
+ {
+ /* socket is ready for writing = success. */
+ }
+ else
+ {
+ /* socket error */
g_object_unref (data->current_socket);
data->current_socket = NULL;
@@ -169,20 +170,12 @@ g_socket_client_socket_callback (GSocketClientAsyncConnectData *data,
return FALSE;
}
- else /* cancelled */
- {
- gboolean cancelled;
-
- cancelled = g_cancellable_set_error_if_cancelled (data->cancellable,
- &data->last_error);
- g_assert (cancelled);
- }
-
g_socket_client_async_connect_complete (data);
return FALSE;
}
+
static void
g_socket_client_enumerator_callback (GObject *object,
GAsyncResult *result,
@@ -196,10 +189,9 @@ g_socket_client_enumerator_callback (GObject *object,
address = g_socket_address_enumerator_next_finish (data->enumerator,
result, &tmp_error);
-
- if ((address || tmp_error) && data->last_error)
+ if (address || tmp_error)
g_clear_error (&data->last_error);
-
+
if (tmp_error)
data->last_error = tmp_error;
}
@@ -212,7 +204,19 @@ g_socket_client_enumerator_callback (GObject *object,
GSocket *socket;
class = G_SOCKET_CLIENT_GET_CLASS (data->client);
- socket = class->socket_factory (data->client, address);
+ socket = class->socket_factory (data->client, address, &tmp_error);
+
+ if (socket == NULL)
+ {
+ g_clear_error (&data->last_error);
+ data->last_error = tmp_error;
+ g_socket_address_enumerator_next_async (data->enumerator,
+ data->cancellable,
+ g_socket_client_enumerator_callback,
+ data);
+ g_object_unref (address);
+ return;
+ }
g_socket_set_blocking (socket, FALSE);
pending = (g_socket_connect (socket, address, &tmp_error) == FALSE) &&
diff --git a/gio/gsocketclient.h b/gio/gsocketclient.h
index af39bd5..014633a 100644
--- a/gio/gsocketclient.h
+++ b/gio/gsocketclient.h
@@ -46,7 +46,8 @@ struct _GSocketClientClass
GSocketConnection * (* connection_factory) (GSocketClient *client,
GSocket *socket);
GSocket * (* socket_factory) (GSocketClient *client,
- GSocketAddress *address);
+ GSocketAddress *address,
+ GError **error);
gpointer padding[5];
};
diff --git a/gio/gtcpclient.c b/gio/gtcpclient.c
index 5edd09d..19df7ab 100644
--- a/gio/gtcpclient.c
+++ b/gio/gtcpclient.c
@@ -630,10 +630,11 @@ g_tcp_client_connection_factory (GSocketClient *client,
static GSocket *
g_tcp_client_socket_factory (GSocketClient *client,
- GSocketAddress *address)
+ GSocketAddress *address,
+ GError **error)
{
return G_SOCKET_CLIENT_CLASS (g_tcp_client_parent_class)
- ->socket_factory (client, address);
+ ->socket_factory (client, address, error);
}
static void
diff --git a/gio/gtcplistener.c b/gio/gtcplistener.c
index b53c596..02a2c1a 100644
--- a/gio/gtcplistener.c
+++ b/gio/gtcplistener.c
@@ -55,7 +55,7 @@ g_tcp_listener_socket_factory (GSocketListener *listener,
GSocketFamily family;
family = g_inet_address_get_family (tcp_listener->priv->address);
- socket = g_socket_new (family, G_SOCKET_TYPE_STREAM, NULL);
+ 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)
@@ -67,9 +67,9 @@ g_tcp_listener_socket_factory (GSocketListener *listener,
/* try to get a hybrid ipv6/ipv4 socket first */
socket = g_socket_new (G_SOCKET_FAMILY_IPV6,
G_SOCKET_TYPE_STREAM,
- NULL);
+ NULL, NULL);
- if (!g_socket_has_error (socket, NULL))
+ if (socket != NULL)
/* we can do ipv6, so bind to :: */
address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
@@ -78,12 +78,12 @@ g_tcp_listener_socket_factory (GSocketListener *listener,
{
socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
G_SOCKET_TYPE_STREAM,
- NULL);
+ NULL, error);
address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
}
}
- if (g_socket_has_error (socket, error))
+ if (socket == NULL)
return NULL;
g_socket_set_reuse_address (socket, TRUE);
diff --git a/gio/gunixclient.c b/gio/gunixclient.c
index d1d3a39..f2229b9 100644
--- a/gio/gunixclient.c
+++ b/gio/gunixclient.c
@@ -159,10 +159,11 @@ g_unix_client_connection_factory (GSocketClient *client,
static GSocket *
g_unix_client_socket_factory (GSocketClient *client,
- GSocketAddress *address)
+ GSocketAddress *address,
+ GError **error)
{
return G_SOCKET_CLIENT_CLASS (g_unix_client_parent_class)
- ->socket_factory (client, address);
+ ->socket_factory (client, address, error);
}
static void
diff --git a/gio/gunixlistener.c b/gio/gunixlistener.c
index 0fc89e5..4cba4ca 100644
--- a/gio/gunixlistener.c
+++ b/gio/gunixlistener.c
@@ -47,7 +47,10 @@ g_unix_listener_socket_factory (GSocketListener *listener,
socket = g_socket_new (G_SOCKET_FAMILY_UNIX,
G_SOCKET_TYPE_STREAM,
- NULL);
+ NULL, error);
+ if (socket == NULL)
+ return NULL;
+
sockaddr = g_unix_socket_address_new (unix_listener->priv->path);
/* XXX fix */
diff --git a/test/server.c b/test/server.c
index 904bb30..11a93ed 100644
--- a/test/server.c
+++ b/test/server.c
@@ -143,9 +143,9 @@ main (int argc,
else
socket_type = G_SOCKET_TYPE_STREAM;
- socket = g_socket_new (G_SOCKET_FAMILY_IPV4, socket_type, NULL);
+ socket = g_socket_new (G_SOCKET_FAMILY_IPV4, socket_type, NULL, &error);
- if (g_socket_has_error (socket, &error))
+ if (socket == NULL)
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]