summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J Stevens <paul@nfg.nl>2010-04-22 16:59:02 +0200
committerPaul J Stevens <paul@nfg.nl>2010-04-22 17:38:30 +0200
commitb6df3fb9ae10b58078d7d46bf3a7d7f9ea483944 (patch)
treee946d168c42f1df0c036462602955b68f7ed05e9
parent3f41ea95cafef3263622d539bafc8cb9471d2de5 (diff)
handle write event starvation
-rw-r--r--src/clientbase.c53
-rw-r--r--src/imap4.c2
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);
}