diff src/protocols/yahoo/ycht.c @ 13200:33bef17125c2

[gaim-migrate @ 15563] This is the soon-to-be-infamous nonblocking network activity patch that I've been working on. Feel free to yell at me if this makes you unhappy. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 09 Feb 2006 04:17:56 +0000
parents f4e58e94ced3
children 10e8eb6a4910
line wrap: on
line diff
--- a/src/protocols/yahoo/ycht.c	Thu Feb 09 04:14:54 2006 +0000
+++ b/src/protocols/yahoo/ycht.c	Thu Feb 09 04:17:56 2006 +0000
@@ -265,9 +265,39 @@
 	return ret;
 }
 
+static void ycht_packet_send_write_cb(gpointer data, gint source, GaimInputCondition cond)
+{
+	YchtConn *ycht = data;
+	int ret, writelen;
+
+	writelen = gaim_circ_buffer_get_max_read(ycht->txbuf);
+
+	if (writelen == 0) {
+		gaim_input_remove(ycht->tx_handler);
+		ycht->tx_handler = 0;
+		return;
+	}
+
+	ret = write(ycht->fd, ycht->txbuf->outptr, writelen);
+
+	if (ret < 0 && errno == EAGAIN)
+		return;
+	else if (ret <= 0) {
+		/* TODO: error handling */
+/*
+		gaim_connection_error(gaim_account_get_connection(irc->account),
+			      _("Server has disconnected"));
+*/
+		return;
+	}
+
+	gaim_circ_buffer_mark_read(ycht->txbuf, ret);
+
+}
+
 static void ycht_packet_send(YchtConn *ycht, YchtPkt *pkt)
 {
-	int len, pos;
+	int len, pos, written;
 	char *buf;
 	GList *l;
 
@@ -295,7 +325,29 @@
 		}
 	}
 
-	write(ycht->fd, buf, len);
+	if (!ycht->tx_handler)
+		written = write(ycht->fd, buf, len);
+	else {
+		written = -1;
+		errno = EAGAIN;
+	}
+
+	if (written < 0 && errno == EAGAIN)
+		written = 0;
+	else if (written <= 0) {
+		/* TODO: Error handling (was none before NBIO changes) */
+		written = 0;
+	}
+
+	if (written < len) {
+		if (!ycht->tx_handler)
+			ycht->tx_handler = gaim_input_add(ycht->fd,
+				GAIM_INPUT_WRITE, ycht_packet_send_write_cb,
+				ycht);
+		gaim_circ_buffer_append(ycht->txbuf, buf + written,
+			len - written);
+	}
+
 	g_free(buf);
 }
 
@@ -388,8 +440,12 @@
 	if (ycht->inpa)
 		gaim_input_remove(ycht->inpa);
 
-	if (ycht->rxqueue)
-		g_free(ycht->rxqueue);
+	if (ycht->tx_handler)
+		gaim_input_remove(ycht->tx_handler);
+
+	gaim_circ_buffer_destroy(ycht->txbuf);
+
+	g_free(ycht->rxqueue);
 
 	g_free(ycht);
 }
@@ -409,6 +465,9 @@
 
 	len = read(ycht->fd, buf, sizeof(buf));
 
+	if (len < 0 && errno == EAGAIN)
+		return;
+
 	if (len <= 0) {
 		ycht_connection_error(ycht, _("Unable to read"));
 		return;
@@ -529,8 +588,7 @@
 	char *tmp;
 
 	tmp = g_strdup(room);
-	if (ycht->room)
-		g_free(ycht->room);
+	g_free(ycht->room);
 	ycht->room = tmp;
 
 	if (!ycht->logged_in)