[libsoup] Bug 574414 – Make SOUP_SESSION_TIMEOUT work with SoupSessionAsync
- From: Dan Winship <danw src gnome org>
- To: svn-commits-list gnome org
- Subject: [libsoup] Bug 574414 – Make SOUP_SESSION_TIMEOUT work with SoupSessionAsync
- Date: Sat, 18 Apr 2009 09:13:45 -0400 (EDT)
commit c3c420f75359da299ffa8912e595c8b99ac40912
Author: Dan Winship <danw gnome org>
Date: Sat Apr 18 08:29:28 2009 -0400
Bug 574414 â?? Make SOUP_SESSION_TIMEOUT work with SoupSessionAsync
soup-socket.c: when adding an IO watch to wait for an async socket to
become readable/writable, add a timeout as well, and fail if the
timeout times out.
soup-connection.c: Pass the TIMEOUT flag to async sockets too
---
libsoup/soup-connection.c | 1 +
libsoup/soup-socket.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 4671ce9..99ec6c2 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -540,6 +540,7 @@ address_resolved (SoupAddress *addr, guint status, gpointer data)
soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, addr,
SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
+ SOUP_SOCKET_TIMEOUT, priv->io_timeout,
NULL);
soup_socket_connect_async (priv->socket, NULL,
socket_connect_result, conn);
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index f7b1a5c..d3f77f9 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -68,11 +68,13 @@ typedef struct {
guint non_blocking:1;
guint is_server:1;
+ guint timed_out:1;
gpointer ssl_creds;
GMainContext *async_context;
GSource *watch_src;
GSource *read_src, *write_src;
+ GSource *read_timeout, *write_timeout;
GByteArray *read_buf;
GMutex *iolock, *addrlock;
@@ -129,6 +131,14 @@ disconnect_internal (SoupSocketPrivate *priv)
g_source_destroy (priv->write_src);
priv->write_src = NULL;
}
+ if (priv->read_timeout) {
+ g_source_destroy (priv->read_timeout);
+ priv->read_timeout = NULL;
+ }
+ if (priv->write_timeout) {
+ g_source_destroy (priv->write_timeout);
+ priv->write_timeout = NULL;
+ }
}
static void
@@ -1100,7 +1110,29 @@ soup_socket_get_remote_address (SoupSocket *sock)
}
+static gboolean
+socket_timeout (gpointer sock)
+{
+ SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
+ gboolean readable = FALSE, writable = FALSE;
+
+ priv->timed_out = TRUE;
+ if (priv->read_timeout) {
+ priv->read_timeout = NULL;
+ readable = TRUE;
+ }
+ if (priv->write_timeout) {
+ priv->write_timeout = NULL;
+ writable = TRUE;
+ }
+
+ if (readable)
+ g_signal_emit (sock, signals[READABLE], 0);
+ if (writable)
+ g_signal_emit (sock, signals[WRITABLE], 0);
+ return FALSE;
+}
static gboolean
socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
@@ -1109,6 +1141,10 @@ socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
priv->read_src = NULL;
+ if (priv->read_timeout) {
+ g_source_destroy (priv->read_timeout);
+ priv->read_timeout = NULL;
+ }
if (cond & (G_IO_ERR | G_IO_HUP))
soup_socket_disconnect (sock);
@@ -1132,6 +1168,9 @@ read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
if (!priv->iochannel)
return SOUP_SOCKET_EOF;
+ if (priv->timed_out)
+ return SOUP_SOCKET_ERROR;
+
status = g_io_channel_read_chars (priv->iochannel,
buffer, len, nread, &my_err);
if (my_err) {
@@ -1162,6 +1201,12 @@ read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
priv->iochannel,
cond | G_IO_HUP | G_IO_ERR,
socket_read_watch, sock);
+ if (priv->timeout) {
+ priv->read_timeout =
+ soup_add_timeout (priv->async_context,
+ priv->timeout * 1000,
+ socket_timeout, sock);
+ }
}
g_clear_error (error);
return SOUP_SOCKET_WOULD_BLOCK;
@@ -1351,6 +1396,10 @@ socket_write_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
priv->write_src = NULL;
+ if (priv->write_timeout) {
+ g_source_destroy (priv->write_timeout);
+ priv->write_timeout = NULL;
+ }
if (cond & (G_IO_ERR | G_IO_HUP))
soup_socket_disconnect (sock);
@@ -1407,6 +1456,10 @@ soup_socket_write (SoupSocket *sock, gconstpointer buffer,
g_mutex_unlock (priv->iolock);
return SOUP_SOCKET_EOF;
}
+ if (priv->timed_out) {
+ g_mutex_unlock (priv->iolock);
+ return SOUP_SOCKET_ERROR;
+ }
if (priv->write_src) {
g_mutex_unlock (priv->iolock);
return SOUP_SOCKET_WOULD_BLOCK;
@@ -1446,6 +1499,12 @@ soup_socket_write (SoupSocket *sock, gconstpointer buffer,
priv->iochannel,
cond | G_IO_HUP | G_IO_ERR,
socket_write_watch, sock);
+ if (priv->timeout) {
+ priv->write_timeout = soup_add_timeout (priv->async_context,
+ priv->timeout * 1000,
+ socket_timeout, sock);
+ }
+
g_mutex_unlock (priv->iolock);
return SOUP_SOCKET_WOULD_BLOCK;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]