ft: Fix ui_ops->ui_read being called too often (when it's not ready).

Tue, 26 Jan 2010 19:26:36 +0000

author
Paul Aurich <darkrain42@pidgin.im>
date
Tue, 26 Jan 2010 19:26:36 +0000
changeset 29232
a94f1f9cdcd2
parent 29231
08f6bc58f696
child 29233
a686b1d2f50f

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.

libpurple/ft.c file | annotate | diff | comparison | revisions
--- 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);

mercurial