Mercurial > pidgin
diff src/protocols/msn/servconn.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 | 4e7ba55a1db2 |
children | 8754a0fe2297 |
line wrap: on
line diff
--- a/src/protocols/msn/servconn.c Thu Feb 09 04:14:54 2006 +0000 +++ b/src/protocols/msn/servconn.c Thu Feb 09 04:17:56 2006 +0000 @@ -50,6 +50,9 @@ servconn->num = session->servconns_count++; + servconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN); + servconn->tx_handler = -1; + return servconn; } @@ -73,8 +76,11 @@ if (servconn->httpconn != NULL) msn_httpconn_destroy(servconn->httpconn); - if (servconn->host != NULL) - g_free(servconn->host); + g_free(servconn->host); + + gaim_circ_buffer_destroy(servconn->tx_buf); + if (servconn->tx_handler > 0) + gaim_input_remove(servconn->tx_handler); msn_cmdproc_destroy(servconn->cmdproc); g_free(servconn); @@ -181,7 +187,7 @@ /* Someone wants to know we connected. */ servconn->connect_cb(servconn); servconn->inpa = gaim_input_add(servconn->fd, GAIM_INPUT_READ, - read_cb, data); + read_cb, data); } else { @@ -227,7 +233,7 @@ } r = gaim_proxy_connect(session->account, host, port, connect_cb, - servconn); + servconn); if (r == 0) { @@ -279,30 +285,72 @@ servconn->disconnect_cb(servconn); } +static void +servconn_write_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnServConn *servconn = data; + int ret, writelen; + + writelen = gaim_circ_buffer_get_max_read(servconn->tx_buf); + + if (writelen == 0) { + gaim_input_remove(servconn->tx_handler); + servconn->tx_handler = -1; + return; + } + + ret = write(servconn->fd, servconn->tx_buf->outptr, writelen); + + if (ret < 0 && errno == EAGAIN) + return; + else if (ret <= 0) { + msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE); + return; + } + + gaim_circ_buffer_mark_read(servconn->tx_buf, ret); +} + size_t msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len) { - size_t ret = FALSE; + size_t ret = 0; g_return_val_if_fail(servconn != NULL, 0); if (!servconn->session->http_method) { - switch (servconn->type) - { - case MSN_SERVCONN_NS: - case MSN_SERVCONN_SB: - ret = write(servconn->fd, buf, len); - break; + if (servconn->tx_handler == -1) { + switch (servconn->type) + { + case MSN_SERVCONN_NS: + case MSN_SERVCONN_SB: + ret = write(servconn->fd, buf, len); + break; #if 0 - case MSN_SERVCONN_DC: - ret = write(servconn->fd, &buf, sizeof(len)); - ret = write(servconn->fd, buf, len); - break; + case MSN_SERVCONN_DC: + ret = write(servconn->fd, &buf, sizeof(len)); + ret = write(servconn->fd, buf, len); + break; #endif - default: - ret = write(servconn->fd, buf, len); - break; + default: + ret = write(servconn->fd, buf, len); + break; + } + } else { + ret = -1; + errno = EAGAIN; + } + + if (ret < 0 && errno == EAGAIN) + ret = 0; + if (ret < len) { + if (servconn->tx_handler == -1) + servconn->tx_handler = gaim_input_add( + servconn->fd, GAIM_INPUT_WRITE, + servconn_write_cb, servconn); + gaim_circ_buffer_append(servconn->tx_buf, buf + ret, + len - ret); } } else @@ -332,7 +380,9 @@ len = read(servconn->fd, buf, sizeof(buf) - 1); - if (len <= 0) + if (len < 0 && errno == EAGAIN) + return; + else if (len <= 0) { gaim_debug_error("msn", "servconn read error, len: %d error: %s\n", len, strerror(errno)); msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ);