diff options
author | Paul J Stevens <paul@nfg.nl> | 2010-04-22 16:59:02 +0200 |
---|---|---|
committer | Paul J Stevens <paul@nfg.nl> | 2010-04-22 17:38:30 +0200 |
commit | b6df3fb9ae10b58078d7d46bf3a7d7f9ea483944 (patch) | |
tree | e946d168c42f1df0c036462602955b68f7ed05e9 | |
parent | 3f41ea95cafef3263622d539bafc8cb9471d2de5 (diff) |
handle write event starvation
-rw-r--r-- | src/clientbase.c | 53 | ||||
-rw-r--r-- | src/imap4.c | 2 |
2 files changed, 29 insertions, 26 deletions
diff --git a/src/clientbase.c b/src/clientbase.c index 3ebb0921..eb320817 100644 --- a/src/clientbase.c +++ b/src/clientbase.c @@ -288,37 +288,40 @@ int ci_write(clientbase_t *self, char * msg, ...) s = self->write_buffer->str + self->write_buffer_offset; n = self->write_buffer->len - self->write_buffer_offset; - if (n > TLS_SEGMENT) n = TLS_SEGMENT; + while (n > 0) { + if (n > TLS_SEGMENT) n = TLS_SEGMENT; - if (self->ssl) { - if (! self->tls_wbuf_n) { - strncpy(self->tls_wbuf, s, n); - self->tls_wbuf_n = n; - } - t = SSL_write(self->ssl, (gconstpointer)self->tls_wbuf, self->tls_wbuf_n); - e = t; - } else { - t = write(self->tx, (gconstpointer)s, n); - e = errno; - } - - if (t == -1) { - if ((e = self->cb_error(self->tx, e, (void *)self))) { - self->client_state |= CLIENT_ERR; - return e; - } - } else { - self->bytes_tx += t; // Update our byte counter if (self->ssl) { - memset(self->tls_wbuf, '\0', TLS_SEGMENT); - self->tls_wbuf_n = 0; + if (! self->tls_wbuf_n) { + strncpy(self->tls_wbuf, s, n); + self->tls_wbuf_n = n; + } + t = SSL_write(self->ssl, (gconstpointer)self->tls_wbuf, self->tls_wbuf_n); + e = t; + } else { + t = write(self->tx, (gconstpointer)s, n); + e = errno; } - self->write_buffer_offset += t; - TRACE(TRACE_INFO, "[%p] S > [%u/%u:%s]", self, self->write_buffer_offset, self->write_buffer->len, s); + if (t == -1) { + if ((e = self->cb_error(self->tx, e, (void *)self))) { + self->client_state |= CLIENT_ERR; + return e; + } + } else { + event_add(self->wev, NULL); - client_wbuf_scale(self); + self->bytes_tx += t; // Update our byte counter + if (self->ssl) { + memset(self->tls_wbuf, '\0', TLS_SEGMENT); + self->tls_wbuf_n = 0; + } + self->write_buffer_offset += t; + TRACE(TRACE_INFO, "[%p] S > [%u/%u:%s]", self, self->write_buffer_offset, self->write_buffer->len, s); + client_wbuf_scale(self); + } + n = self->write_buffer->len - self->write_buffer_offset; } return 0; diff --git a/src/imap4.c b/src/imap4.c index f183022f..3331e7dc 100644 --- a/src/imap4.c +++ b/src/imap4.c @@ -275,7 +275,6 @@ static void imap_handle_exit(ImapSession *session, int status) dbmail_imap_session_buff_clear(session); } if ((session->ci->write_buffer->len - session->ci->write_buffer_offset) > 0) { - TRACE(TRACE_DEBUG,"write_buffer size: %lu", (session->ci->write_buffer->len - session->ci->write_buffer_offset)); ci_write(session->ci, NULL); } else if (session->command_state == TRUE) { dbmail_imap_session_reset(session); @@ -540,6 +539,7 @@ void _ic_cb_leave(gpointer data) ImapSession *session = D->session; TRACE(TRACE_DEBUG,"handling imap session [%p]",session); + ci_uncork(session->ci); imap_handle_exit(session, D->status); } |