changeset 28911:a41724547756

ft: Fix ui_ops->ui_read being called too often (when it's not ready). Also fix a deadlock case stemming from that, where ui_read() returns 0, but when it next calls purple_xfer_ui_ready(), libpurple doesn't think the prpl is ready.
author Paul Aurich <paul@darkrain42.org>
date Tue, 26 Jan 2010 19:26:36 +0000
parents 708e89126ba1
children c833ae72599b
files libpurple/ft.c
diffstat 1 files changed, 11 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/ft.c	Tue Jan 26 02:22:22 2010 +0000
+++ b/libpurple/ft.c	Tue Jan 26 19:26:36 2010 +0000
@@ -1090,17 +1090,22 @@
 		if (ui_ops && ui_ops->ui_read) {
 			gssize tmp = ui_ops->ui_read(xfer, &buffer, s);
 			if (tmp == 0) {
+				PurpleXferPrivData *priv = g_hash_table_lookup(xfers_data, xfer);
+
 				/*
-				 * UI isn't ready to send data. It will call
-				 * purple_xfer_ui_ready when ready, which sets back up this
-				 * watcher.
+				 * The UI claimed it was ready, but didn't have any data for
+				 * us...  It will call purple_xfer_ui_ready when ready, which
+				 * sets back up this watcher.
 				 */
 				if (xfer->watcher != 0) {
 					purple_input_remove(xfer->watcher);
 					xfer->watcher = 0;
 				}
 
-				return;
+				/* Need to indicate the prpl is still ready... */
+				priv->ready |= PURPLE_XFER_READY_PRPL;
+
+				g_return_if_reached();
 			} else if (tmp < 0) {
 				purple_debug_error("filetransfer", "Unable to read whole buffer.\n");
 				purple_xfer_cancel_local(xfer);
@@ -1181,6 +1186,8 @@
 			purple_debug_misc("xfer", "prpl is ready on ft %p, waiting for UI\n", xfer);
 			return;
 		}
+
+		priv->ready = PURPLE_XFER_READY_NONE;
 	}
 
 	do_transfer(xfer);