[evolution-patches] possible fix for the soup connection_death loop
- From: Dan Winship <danw ximian com>
- To: evolution-patches ximian com
- Cc: Joe Shaw <joe ximian com>
- Subject: [evolution-patches] possible fix for the soup connection_death loop
- Date: 07 May 2003 19:13:33 -0400
I was trying to fix 42468, which turned out to be our old friend the
connection_death loop. There are actually 3 fixes in this patch:
1. Only set a death watch on the connection when in_use is FALSE,
so that we can always destroy it when connection_death is
called, rather than returning FALSE and getting into an infinite
loop.
2. Fix a double free situation in soup-transfer made more common by
that fix
3. Fix the new infinite loop that 42468 turns into with that fix
because the connection was never getting marked as not-new.
With those 3 fixes... 42468 *still* gets into an infinite loop, now
because of bugs in the NTLM logic. (It keeps forgetting that it's in the
middle of authenticating and starts over.) I'm still working on that
part, and I'm not going to commit this until I've figured that out too,
but those fixes should be orthogonal to these ones.
Index: soup-context.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-context.c,v
retrieving revision 1.48
diff -u -r1.48 soup-context.c
--- soup-context.c 11 Apr 2003 17:02:29 -0000 1.48
+++ soup-context.c 7 May 2003 22:55:40 -0000
@@ -260,7 +260,8 @@
g_io_channel_unref (conn->channel);
soup_context_unref (conn->context);
soup_socket_unref (conn->socket);
- g_source_remove (conn->death_tag);
+ if (conn->death_tag)
+ g_source_remove (conn->death_tag);
g_free (conn);
connection_count--;
@@ -271,12 +272,31 @@
GIOCondition condition,
SoupConnection *conn)
{
+ connection_free (conn);
+ return FALSE;
+}
+
+static void
+soup_connection_set_in_use (SoupConnection *conn, gboolean in_use)
+{
+ if (in_use == conn->in_use)
+ return;
+
+ conn->in_use = in_use;
if (!conn->in_use) {
- connection_free (conn);
- return FALSE;
- }
+ GIOChannel *chan;
- return TRUE;
+ chan = soup_connection_get_iochannel (conn);
+ conn->death_tag =
+ g_io_add_watch (chan,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ (GIOFunc) connection_death,
+ conn);
+ g_io_channel_unref (chan);
+ } else {
+ g_source_remove (conn->death_tag);
+ conn->death_tag = 0;
+ }
}
struct SoupConnectData {
@@ -334,7 +354,6 @@
struct SoupConnectData *data = user_data;
SoupContext *ctx = data->ctx;
SoupConnection *new_conn;
- GIOChannel *chan;
switch (status) {
case SOUP_SOCKET_CONNECT_ERROR_NONE:
@@ -344,19 +363,12 @@
new_conn->port = ctx->uri->port;
new_conn->keep_alive = TRUE;
new_conn->in_use = TRUE;
+ new_conn->new = TRUE;
new_conn->last_used_id = 0;
new_conn->context = ctx;
soup_context_ref (ctx);
- chan = soup_connection_get_iochannel (new_conn);
- new_conn->death_tag =
- g_io_add_watch (chan,
- G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- (GIOFunc) connection_death,
- new_conn);
- g_io_channel_unref (chan);
-
ctx->server->connections =
g_slist_prepend (ctx->server->connections, new_conn);
@@ -414,7 +426,7 @@
conn->keep_alive == TRUE &&
conn->port == (guint) ctx->uri->port) {
/* Set connection to in use */
- conn->in_use = TRUE;
+ soup_connection_set_in_use (conn, TRUE);
/* Reset connection context */
soup_context_ref (ctx);
@@ -589,7 +601,7 @@
if (conn->keep_alive) {
conn->last_used_id = ++most_recently_used_id;
- conn->in_use = FALSE;
+ soup_connection_set_in_use (conn, FALSE);
} else
connection_free (conn);
}
@@ -688,11 +700,25 @@
}
/**
+ * soup_connection_set_used:
+ * @conn: a %SoupConnection.
+ *
+ * Clears the "new" flag on @conn.
+ */
+void
+soup_connection_set_used (SoupConnection *conn)
+{
+ g_return_if_fail (conn != NULL);
+
+ conn->new = FALSE;
+}
+
+/**
* soup_connection_is_new:
* @conn: a %SoupConnection.
*
* Returns TRUE if this is the first use of @conn
- * (I.E. %soup_connection_release has not yet been called on it).
+ * (I.E. no response has been read from it yet)
*
* Return value: boolean representing whether this is the first time a
* connection has been used.
@@ -701,7 +727,7 @@
soup_connection_is_new (SoupConnection *conn)
{
g_return_val_if_fail (conn != NULL, FALSE);
- return conn->last_used_id == 0;
+ return conn->new;
}
Index: soup-context.h
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-context.h,v
retrieving revision 1.16
diff -u -r1.16 soup-context.h
--- soup-context.h 11 Apr 2003 17:02:29 -0000 1.16
+++ soup-context.h 7 May 2003 22:55:41 -0000
@@ -57,6 +57,7 @@
gboolean soup_connection_is_keep_alive (SoupConnection *conn);
+void soup_connection_set_used (SoupConnection *conn);
gboolean soup_connection_is_new (SoupConnection *conn);
void soup_connection_release (SoupConnection *conn);
Index: soup-message.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-message.c,v
retrieving revision 1.55
diff -u -r1.55 soup-message.c
--- soup-message.c 6 May 2003 13:00:52 -0000 1.55
+++ soup-message.c 7 May 2003 22:55:41 -0000
@@ -582,6 +582,7 @@
SoupMessage *msg = data->msg;
SoupConnection *conn = msg->connection;
+ soup_connection_set_used (msg->connection);
if (!soup_connection_is_keep_alive (msg->connection))
requeue_read_error (FALSE, data);
else {
Index: soup-private.h
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-private.h,v
retrieving revision 1.53
diff -u -r1.53 soup-private.h
--- soup-private.h 15 Nov 2002 16:26:42 -0000 1.53
+++ soup-private.h 7 May 2003 22:55:41 -0000
@@ -82,6 +82,7 @@
guint last_used_id;
gboolean keep_alive;
guint death_tag;
+ gboolean new;
};
struct _SoupServer {
Index: soup-queue.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-queue.c,v
retrieving revision 1.80
diff -u -r1.80 soup-queue.c
--- soup-queue.c 25 Apr 2003 17:34:08 -0000 1.80
+++ soup-queue.c 7 May 2003 22:55:41 -0000
@@ -112,6 +112,9 @@
soup_message_issue_callback (req);
break;
}
+
+ if (req->connection)
+ soup_connection_set_used (req->connection);
}
static SoupTransferDone
@@ -246,6 +249,8 @@
gpointer user_data)
{
SoupMessage *req = user_data;
+
+ soup_connection_set_used (req->connection);
req->response.owner = data->owner;
req->response.length = data->length;
Index: soup-transfer.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-transfer.c,v
retrieving revision 1.29
diff -u -r1.29 soup-transfer.c
--- soup-transfer.c 29 Apr 2003 16:02:24 -0000 1.29
+++ soup-transfer.c 7 May 2003 22:55:41 -0000
@@ -448,8 +448,10 @@
PROCESS_READ:
- if (r->header_len == 0 && total_read == 0)
- goto FINISH_READ;
+ if (r->header_len == 0 && total_read == 0) {
+ soup_transfer_read_error_cb (iochannel, G_IO_HUP, r);
+ return FALSE;
+ }
if (r->header_len == 0) {
gint index;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]