From 041acdd0edc340e7b6008b84e2ff6791c0d22713 Mon Sep 17 00:00:00 2001 From: Samuel Cormier-Iijima Date: Thu, 28 Feb 2008 02:59:44 -0500 Subject: [PATCH] Remove the async stuff per IRC discussion --- gnio/gsocket.c | 312 +++++++++------------------------------------ gnio/gsocket.h | 119 ++++++----------- test/test-client.c | 6 +- test/test-server.c | 19 ++- 4 files changed, 122 insertions(+), 334 deletions(-) diff --git a/gnio/gsocket.c b/gnio/gsocket.c index f9410bf..1a095ef 100644 --- a/gnio/gsocket.c +++ b/gnio/gsocket.c @@ -52,13 +52,17 @@ enum { PROP_0, PROP_FD, - PROP_BLOCKING + PROP_BLOCKING, + PROP_LOCAL_ADDRESS, + PROP_REMOTE_ADDRESS }; struct _GSocketPrivate { gint fd; gboolean blocking; + GSocketAddress *local_address; + GSocketAddress *remote_address; }; static void @@ -76,6 +80,14 @@ g_socket_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec g_value_set_boolean (value, socket->priv->blocking); break; + case PROP_LOCAL_ADDRESS: + g_value_set_object (value, socket->priv->local_address); + break; + + case PROP_REMOTE_ADDRESS: + g_value_set_object (value, socket->priv->remote_address); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -124,6 +136,8 @@ g_socket_class_init (GSocketClass *klass) { GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass); + // TODO: WSAStartup + g_type_class_add_private (klass, sizeof (GSocketPrivate)); gobject_class->finalize = g_socket_finalize; @@ -146,6 +160,20 @@ g_socket_class_init (GSocketClass *klass) "whether or not this socket is blocking", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); + + g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS, + g_param_spec_object ("local-address", + "local address", + "the local address the socket is bound to", + G_TYPE_SOCKET_ADDRESS, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); + + g_object_class_install_property (gobject_class, PROP_REMOTE_ADDRESS, + g_param_spec_object ("remote-address", + "remote address", + "the remote address the socket is connected to", + G_TYPE_SOCKET_ADDRESS, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); } static void @@ -155,6 +183,8 @@ g_socket_init (GSocket *socket) socket->priv->fd = -1; socket->priv->blocking = TRUE; + socket->priv->remote_address = NULL; + socket->priv->local_address = NULL; } GSocket * @@ -270,21 +300,45 @@ g_socket_get_blocking (GSocket *socket) } GSocketAddress * -g_socket_get_peer_address (GSocket *socket, - GError **error) +g_socket_get_local_address (GSocket *socket, + GError **error) { gchar buffer[256]; gsize len; g_return_val_if_fail (G_IS_SOCKET (socket), NULL); + if (socket->priv->local_address) + return socket->priv->local_address; + + if (getsockname (socket->priv->fd, (struct sockaddr *) buffer, &len) < 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not get local address: %s", g_strerror (errno)); + return NULL; + } + + return (socket->priv->local_address = g_object_ref_sink (g_socket_address_from_native (buffer, len))); +} + +GSocketAddress * +g_socket_get_remote_address (GSocket *socket, + GError **error) +{ + gchar buffer[256]; + gsize len; + + g_return_val_if_fail (G_IS_SOCKET (socket), NULL); + + if (socket->priv->remote_address) + return socket->priv->remote_address; + if (getpeername (socket->priv->fd, (struct sockaddr *) buffer, &len) < 0) { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not get peer address: %s", g_strerror (errno)); + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not get remote address: %s", g_strerror (errno)); return NULL; } - return g_socket_address_from_native (buffer, len); + return (socket->priv->remote_address = g_object_ref_sink (g_socket_address_from_native (buffer, len))); } void @@ -315,7 +369,9 @@ g_socket_bind (GSocket *socket, return FALSE; } - g_object_unref (address); + g_object_ref_sink (address); + + socket->priv->local_address = address; return TRUE; } @@ -323,147 +379,22 @@ g_socket_bind (GSocket *socket, GSocket * g_socket_accept (GSocket *socket, - GCancellable *cancellable, GError **error) { gint ret; - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return NULL; - if ((ret = accept (socket->priv->fd, NULL, 0)) < 0) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "error accepting connection"); return NULL; } - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - { - close (ret); - return NULL; - } - return g_socket_new_from_fd (ret); } -typedef struct { - GAsyncReadyCallback callback; - GCancellable *cancellable; - gpointer user_data; - GSocket *socket; -} AcceptData; - -static gboolean -accept_callback (AcceptData *data, - GIOCondition condition, - gint fd) -{ - GSocket *socket; - GSimpleAsyncResult *result; - gint ret; - - socket = data->socket; - - if (condition & G_IO_IN) - { - if ((ret = accept (socket->priv->fd, NULL, 0)) < 0) - { - if (errno == EAGAIN) - return TRUE; - - result = g_simple_async_result_new_error (G_OBJECT (socket), data->callback, data->user_data, G_IO_ERROR, g_io_error_from_errno (errno), "error accepting connection"); - } - else - { - result = g_simple_async_result_new (G_OBJECT (socket), data->callback, data->user_data, g_socket_accept_async); - - g_simple_async_result_set_op_res_gpointer (result, g_socket_new_from_fd (ret), g_object_unref); - } - - g_simple_async_result_complete (result); - - g_object_unref (result); - } - - return FALSE; -} - -void -g_socket_accept_async (GSocket *socket, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSource *source; - GSimpleAsyncResult *result; - AcceptData *data; - gint ret; - - g_return_if_fail (G_IS_SOCKET (socket)); - - if (g_socket_get_blocking (socket)) - g_socket_set_blocking (socket, FALSE); - - if ((ret = accept (socket->priv->fd, NULL, 0)) < 0) - { - if (errno == EAGAIN) - { - source = _g_fd_source_new (socket->priv->fd, G_IO_IN | G_IO_HUP | G_IO_ERR, cancellable); - - data = g_new (AcceptData, 1); - - data->socket = socket; - data->callback = callback; - data->cancellable = cancellable; - data->user_data = user_data; - - g_source_set_callback (source, (GSourceFunc) accept_callback, data, g_free); - - g_source_attach (source, NULL); - } - else - { - g_simple_async_report_error_in_idle (G_OBJECT (socket), callback, user_data, G_IO_ERROR, g_io_error_from_errno (errno), "error accepting connection"); - } - } - else - { - result = g_simple_async_result_new (G_OBJECT (socket), callback, user_data, g_socket_accept_async); - - g_simple_async_result_set_op_res_gpointer (result, g_socket_new_from_fd (ret), g_object_unref); - - g_simple_async_result_complete_in_idle (result); - - g_object_unref (result); - } -} - -GSocket * -g_socket_accept_finish (GSocket *socket, - GAsyncResult *result, - GError **error) -{ - GSocket *new_socket; - GSimpleAsyncResult *simple; - - g_return_val_if_fail (G_IS_SOCKET (socket), NULL); - - 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_accept_async); - - new_socket = g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); - - return new_socket; -} - gboolean g_socket_connect (GSocket *socket, GSocketAddress *address, - GCancellable *cancellable, GError **error) { gchar buffer[256]; @@ -481,124 +412,7 @@ g_socket_connect (GSocket *socket, return FALSE; } - return TRUE; -} - -typedef struct { - GAsyncReadyCallback callback; - GCancellable *cancellable; - gpointer user_data; - GSocket *socket; - gchar address_buffer[256]; - gsize address_length; -} ConnectData; - -static gboolean -connect_callback (ConnectData *data, - GIOCondition condition, - gint fd) -{ - GSocket *socket; - GSimpleAsyncResult *result = NULL; - gint sockerr = 0; - gsize sockerr_size = 1; - - socket = data->socket; - - if (condition & G_IO_OUT) - { - result = g_simple_async_result_new (G_OBJECT (socket), data->callback, data->user_data, g_socket_connect_async); - } - else if (condition & G_IO_ERR) - { - if (getsockopt (fd, SOL_SOCKET, SO_ERROR, (gpointer) &sockerr, &sockerr_size) < 0) - g_warning ("getsockopt: %s", g_strerror (errno)); - - if (sockerr != 0) - result = g_simple_async_result_new_error (G_OBJECT (socket), data->callback, data->user_data, G_IO_ERROR, g_io_error_from_errno (sockerr), "error connecting: %s", g_strerror (sockerr)); - else - g_warning ("getsockopt SO_ERROR returned no error, with sockerr = %d", sockerr); - } - - g_simple_async_result_complete (result); - - g_object_unref (result); - - return FALSE; -} - -void -g_socket_connect_async (GSocket *socket, - GSocketAddress *address, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSource *source; - GSimpleAsyncResult *result; - ConnectData *data; - gint ret; - gchar buffer[256]; - gsize len; - - g_return_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address)); - - if (g_socket_get_blocking (socket)) - g_socket_set_blocking (socket, FALSE); - - g_socket_address_to_native (address, buffer); - - len = g_socket_address_native_size (address); - - if ((ret = connect (socket->priv->fd, (struct sockaddr *) buffer, len)) < 0) - { - if (errno == EINPROGRESS) - { - source = _g_fd_source_new (socket->priv->fd, G_IO_OUT | G_IO_ERR, cancellable); - - data = g_new (ConnectData, 1); - - data->socket = socket; - data->callback = callback; - data->cancellable = cancellable; - data->user_data = user_data; - data->address_length = len; - memcpy (data->address_buffer, buffer, len); - - g_source_set_callback (source, (GSourceFunc) connect_callback, data, g_free); - - g_source_attach (source, NULL); - } - else - { - g_simple_async_report_error_in_idle (G_OBJECT (socket), callback, user_data, G_IO_ERROR, g_io_error_from_errno (errno), "error connecting: %s", g_strerror (errno)); - } - } - else - { - result = g_simple_async_result_new (G_OBJECT (socket), callback, user_data, g_socket_connect_async); - - g_simple_async_result_complete_in_idle (result); - - g_object_unref (result); - } -} - -gboolean -g_socket_connect_finish (GSocket *socket, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - if (g_simple_async_result_propagate_error (simple, error)) - return FALSE; - - g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_connect_async); + socket->priv->remote_address = g_object_ref_sink (address); return TRUE; } diff --git a/gnio/gsocket.h b/gnio/gsocket.h index 0affe7c..0f0a5e0 100644 --- a/gnio/gsocket.h +++ b/gnio/gsocket.h @@ -69,87 +69,44 @@ typedef enum G_SOCKET_TYPE_SEQPACKET } GSocketType; -GType g_socket_get_type (void) G_GNUC_CONST; - -GSocket * g_socket_new (GSocketDomain domain, GSocketType type, const gchar *protocol, GError **error); - -GSocket * g_socket_new_from_fd (gint fd); - -GSocketAddress * g_socket_get_peer_address (GSocket *socket, GError **error); - -void g_socket_set_blocking (GSocket *socket, - gboolean blocking); - -gboolean g_socket_get_blocking (GSocket *socket); - -gboolean g_socket_bind (GSocket *socket, - GSocketAddress *address, - GError **error); - -gboolean g_socket_connect (GSocket *socket, - GSocketAddress *address, - GCancellable *cancellable, - GError **error); - -void g_socket_connect_async (GSocket *socket, - GSocketAddress *address, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -gboolean g_socket_connect_finish (GSocket *socket, - GAsyncResult *result, - GError **error); - -GSocket * g_socket_accept (GSocket *socket, - GCancellable *cancellable, - GError **error); - -void g_socket_accept_async (GSocket *socket, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -GSocket * g_socket_accept_finish (GSocket *socket, - GAsyncResult *result, - GError **error); - -void g_socket_listen (GSocket *socket, - gint backlog); - -gssize g_socket_receive (GSocket *socket, - gchar *buffer, - gsize size, - GCancellable *cancellable, - GError **error); - -void g_socket_receive_async (GSocket *socket, - gchar *buffer, - gsize size, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -gssize g_socket_receive_finish (GSocket *socket, - GAsyncResult *result, - GError **error); - -gssize g_socket_send (GSocket *socket, - gchar *buffer, - gsize size, - GCancellable *cancellable, - GError **error); - -void g_socket_send_async (GSocket *socket, - gchar *buffer, - gsize size, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -gssize g_socket_send_finish (GSocket *socket, - GAsyncResult *result, - GError **error); +GType g_socket_get_type (void) G_GNUC_CONST; + +GSocket * g_socket_new (GSocketDomain domain, GSocketType type, const gchar *protocol, GError **error); + +GSocket * g_socket_new_from_fd (gint fd); + +GSocketAddress * g_socket_get_local_address (GSocket *socket, GError **error); + +GSocketAddress * g_socket_get_remote_address (GSocket *socket, GError **error); + +void g_socket_set_blocking (GSocket *socket, + gboolean blocking); + +gboolean g_socket_get_blocking (GSocket *socket); + +gboolean g_socket_bind (GSocket *socket, + GSocketAddress *address, + GError **error); + +gboolean g_socket_connect (GSocket *socket, + GSocketAddress *address, + GError **error); + +GSocket * g_socket_accept (GSocket *socket, + GError **error); + +void g_socket_listen (GSocket *socket, + gint backlog); + +gssize g_socket_receive (GSocket *socket, + gchar *buffer, + gsize size, + GError **error); + +gssize g_socket_send (GSocket *socket, + gchar *buffer, + gsize size, + GError **error); G_END_DECLS diff --git a/test/test-client.c b/test/test-client.c index ea6e8cb..7967aef 100644 --- a/test/test-client.c +++ b/test/test-client.c @@ -8,6 +8,7 @@ GMainLoop *loop; +/* void accept_callback (GSocket *socket, GAsyncResult *result, gpointer data) { @@ -20,6 +21,7 @@ accept_callback (GSocket *socket, GAsyncResult *result, gpointer data) g_print ("successfully connected\n"); } +*/ int main (int argc, char *argv[]) { @@ -35,7 +37,9 @@ int main (int argc, char *argv[]) g_printf ("connecting to 127.0.0.1:31882...\n"); - g_socket_connect_async (socket, G_SOCKET_ADDRESS (g_inet_socket_address_new (G_INET_ADDRESS (g_inet4_address_from_string ("127.0.0.1")), 31882)), NULL, (GAsyncReadyCallback) accept_callback, NULL); + g_socket_connect (socket, G_SOCKET_ADDRESS (g_inet_socket_address_new (G_INET_ADDRESS (g_inet4_address_from_string ("127.0.0.1")), 31882)), NULL); + + g_printf ("connected!\n"); g_main_loop_run (loop); diff --git a/test/test-server.c b/test/test-server.c index dd51b02..8121cc0 100644 --- a/test/test-server.c +++ b/test/test-server.c @@ -10,6 +10,7 @@ GMainLoop *loop; void accept_callback (GSocket *socket, GAsyncResult *result, gpointer data); +/* gboolean accept_source (gpointer data) { @@ -36,7 +37,7 @@ accept_callback (GSocket *socket, GAsyncResult *result, gpointer data) if (!new_socket) g_error (error->message); - address = g_socket_get_peer_address (new_socket, &error); + address = g_socket_get_remote_address (new_socket, &error); if (!address) g_error (error->message); @@ -45,10 +46,12 @@ accept_callback (GSocket *socket, GAsyncResult *result, gpointer data) g_idle_add (accept_source, (gpointer) socket); } +*/ int main (int argc, char *argv[]) { - GSocket *socket; + GSocket *socket, *new_socket; + GSocketAddress *address; GError *error = NULL; g_thread_init (NULL); @@ -66,7 +69,17 @@ int main (int argc, char *argv[]) g_printf ("listening on port 31882...\n"); - g_idle_add (accept_source, (gpointer) socket); + new_socket = g_socket_accept (socket, NULL); + + if (!new_socket) + g_error (error->message); + + address = g_socket_get_remote_address (new_socket, &error); + + if (!address) + g_error (error->message); + + g_printf ("got a new connection from %s:%d\n", g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address))), g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address))); g_main_loop_run (loop); -- 2.20.1