[evolution-patches] soup patch for connection_death loop
- From: Dan Winship <danw ximian com>
- To: evolution-patches ximian com
- Cc: Joe Shaw <joe ximian com>
- Subject: [evolution-patches] soup patch for connection_death loop
- Date: 23 Apr 2003 15:24:53 -0400
This fixes a bug I started encountering yesterday, which might also be
41754. It might also be Joe's soup infinite loop. (It's at least very
similar).
The patch to soup-transfer.c is unfortunate, but that's soup-transfer
for you.
Joe: I'm currently running with both this and my earlier uncommitted
soup patch to split conn->in_use into a tri-state enum. I'm curious if
(a) this patch fixes your loop, and (b) if you need the other patch too
or not.
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/libsoup/ChangeLog,v
retrieving revision 1.297
diff -u -r1.297 ChangeLog
--- ChangeLog 21 Apr 2003 16:06:28 -0000 1.297
+++ ChangeLog 23 Apr 2003 18:34:18 -0000
@@ -1,3 +1,15 @@
+2003-04-23 Dan Winship <danw ximian com>
+
+ * libsoup/soup-message.c (soup_message_cleanup): Don't set up the
+ soup-transfer callbacks to keep reading off the connection unless
+ we're actually going to keep the connection around afterward.
+ Otherwise we can just close it.
+
+ * libsoup/soup-transfer.c: Re-kludge the awful IGNORE_CANCEL
+ thingy so that it's possible to cancel a read from inside a
+ callback so that the above change actually works instead of just
+ crashing.
+
2003-04-20 Rodney Dawes <dobey ximian com>
* configure.in: Up version to 1.99.18
Index: libsoup/soup-message.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-message.c,v
retrieving revision 1.53
diff -u -r1.53 soup-message.c
--- libsoup/soup-message.c 31 Mar 2003 15:32:39 -0000 1.53
+++ libsoup/soup-message.c 23 Apr 2003 18:34:18 -0000
@@ -171,6 +171,7 @@
g_return_if_fail (req != NULL);
if (req->connection &&
+ soup_connection_is_keep_alive (req->connection) &&
req->priv->read_tag &&
req->status == SOUP_STATUS_READING_RESPONSE) {
soup_transfer_read_set_callbacks (req->priv->read_tag,
Index: libsoup/soup-transfer.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-transfer.c,v
retrieving revision 1.27
diff -u -r1.27 soup-transfer.c
--- libsoup/soup-transfer.c 7 Mar 2003 23:02:26 -0000 1.27
+++ libsoup/soup-transfer.c 23 Apr 2003 18:34:18 -0000
@@ -73,7 +73,7 @@
*/
gboolean callback_issued;
- gboolean processing;
+ gboolean *cancelled;
GByteArray *recv_buf;
guint header_len;
@@ -96,7 +96,7 @@
guint write_tag;
guint err_tag;
- gboolean processing;
+ gboolean *cancelled;
SoupTransferEncoding encoding;
GByteArray *write_buf;
@@ -111,15 +111,18 @@
gpointer user_data;
} SoupWriter;
-#define IGNORE_CANCEL(t) (t)->processing = TRUE;
-#define UNIGNORE_CANCEL(t) (t)->processing = FALSE;
+#define IGNORE_CANCEL(t, cancel_p) (t)->cancelled = cancel_p;
+#define UNIGNORE_CANCEL(t) (t)->cancelled = NULL;
void
soup_transfer_read_cancel (guint tag)
{
SoupReader *r = GINT_TO_POINTER (tag);
- if (r->processing) return;
+ if (r->cancelled) {
+ *(r->cancelled) = TRUE;
+ return;
+ }
if (r->read_tag)
g_source_remove (r->read_tag);
@@ -170,9 +173,7 @@
g_source_remove (r->err_tag);
r->read_tag = r->err_tag = 0;
- IGNORE_CANCEL (r);
(*r->read_done_cb) (&buf, r->user_data);
- UNIGNORE_CANCEL (r);
}
}
@@ -182,7 +183,9 @@
SoupReader *r)
{
gboolean body_started = r->recv_buf->len > r->header_len;
+ gboolean cancelled = FALSE;
+ IGNORE_CANCEL (r, &cancelled);
/*
* Closing the connection to signify EOF is valid if content length is
* unknown, but only if headers have been sent.
@@ -192,7 +195,6 @@
goto CANCELLED;
}
- IGNORE_CANCEL (r);
if (r->error_cb) (*r->error_cb) (body_started, r->user_data);
UNIGNORE_CANCEL (r);
@@ -314,14 +316,12 @@
r->callback_issued = TRUE;
- IGNORE_CANCEL (r);
+ IGNORE_CANCEL (r, cancelled);
cont = (*r->read_chunk_cb) (&buf, r->user_data);
UNIGNORE_CANCEL (r);
if (cont == SOUP_TRANSFER_END)
*cancelled = TRUE;
- else
- *cancelled = FALSE;
}
}
@@ -471,14 +471,14 @@
strncpy (str.str, r->recv_buf->data, index);
str.str [index] = '\0';
- IGNORE_CANCEL (r);
+ IGNORE_CANCEL (r, &cancelled);
ret = (*r->headers_done_cb) (&str,
&r->encoding,
&r->content_length,
r->user_data);
UNIGNORE_CANCEL (r);
- if (ret == SOUP_TRANSFER_END)
+ if (ret == SOUP_TRANSFER_END || cancelled)
goto FINISH_READ;
}
@@ -510,7 +510,9 @@
goto READ_AGAIN;
}
+ IGNORE_CANCEL (r, &cancelled);
issue_final_callback (r);
+ UNIGNORE_CANCEL (r);
FINISH_READ:
soup_transfer_read_cancel (GPOINTER_TO_INT (r));
@@ -560,7 +562,10 @@
{
SoupWriter *w = GINT_TO_POINTER (tag);
- if (w->processing) return;
+ if (w->cancelled) {
+ *(w->cancelled) = TRUE;
+ return;
+ }
if (w->write_tag)
g_source_remove (w->write_tag);
@@ -577,7 +582,9 @@
SoupWriter *w)
{
if (w->error_cb) {
- IGNORE_CANCEL (w);
+ gboolean cancelled;
+
+ IGNORE_CANCEL (w, &cancelled);
(*w->error_cb) (w->headers_done, w->user_data);
UNIGNORE_CANCEL (w);
}
@@ -588,11 +595,11 @@
}
static gboolean
-get_header (SoupWriter *w)
+get_header (SoupWriter *w, gboolean *cancelled)
{
GString *header = NULL;
- IGNORE_CANCEL (w);
+ IGNORE_CANCEL (w, cancelled);
(*w->get_header_cb) (&header, w->user_data);
UNIGNORE_CANCEL (w);
@@ -628,12 +635,12 @@
}
static void
-get_next_chunk (SoupWriter *w)
+get_next_chunk (SoupWriter *w, gboolean *cancelled)
{
SoupTransferStatus ret = SOUP_TRANSFER_END;
SoupDataBuffer buf = { 0 , NULL, 0 };
- IGNORE_CANCEL (w);
+ IGNORE_CANCEL (w, cancelled);
ret = (*w->get_chunk_cb) (&buf, w->user_data);
UNIGNORE_CANCEL (w);
@@ -673,16 +680,23 @@
GIOError error;
gpointer pipe_handler;
gsize bytes_written = 0;
+ gboolean cancelled = FALSE;
/*
* Get the header and first data chunk (if available).
*/
if (w->get_header_cb) {
- if (!get_header (w))
+ if (!get_header (w, &cancelled)) {
+ if (cancelled)
+ goto CANCEL;
return TRUE;
+ }
- if (w->get_chunk_cb)
- get_next_chunk (w);
+ if (w->get_chunk_cb) {
+ get_next_chunk (w, &cancelled);
+ if (cancelled)
+ goto CANCEL;
+ }
}
IGNORE_PIPE (pipe_handler);
@@ -721,7 +735,10 @@
* Get the next data chunk and try again, or quit if paused.
*/
if (w->get_chunk_cb) {
- get_next_chunk (w);
+ get_next_chunk (w, &cancelled);
+
+ if (cancelled)
+ goto CANCEL;
if (!w->write_tag)
goto DONE_WRITING;
@@ -730,11 +747,12 @@
}
if (w->write_done_cb) {
- IGNORE_CANCEL (w);
+ IGNORE_CANCEL (w, &cancelled);
(*w->write_done_cb) (w->user_data);
UNIGNORE_CANCEL (w);
}
+ CANCEL:
soup_transfer_write_cancel (GPOINTER_TO_INT (w));
DONE_WRITING:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]