Mercurial > dovecot > core-2.2
changeset 3336:a3a72d5bdfce HEAD
o_stream_uncork() was previously always setting IO_WRITE handler even if
there was no reason for it. This was relied on in imap/pop3 code when a
handler could just send as much data as it can without actually buffering
anything.
So, removed the IO_WRITE handler forcing. It's only set if there's actually
data in buffer or if flush_pending is set (via o_stream_set_flush_pending()
or by returning 0 from flush callback handler).
All in all, a minor optimization.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 26 Apr 2005 13:43:54 +0300 |
parents | ae6f1b54cd59 |
children | b47043d0d131 |
files | src/imap/client.c src/imap/imap-fetch-body.c src/lib/ostream-crlf.c src/lib/ostream-file.c src/lib/ostream-internal.h src/lib/ostream.c src/lib/ostream.h src/pop3/client.c |
diffstat | 8 files changed, 45 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/client.c Tue Apr 26 12:42:59 2005 +0300 +++ b/src/imap/client.c Tue Apr 26 13:43:54 2005 +0300 @@ -337,6 +337,10 @@ _client_reset_command(client); } else { /* unfinished */ + if (client->command_pending) { + o_stream_set_flush_pending(client->output, + TRUE); + } return FALSE; } }
--- a/src/imap/imap-fetch-body.c Tue Apr 26 12:42:59 2005 +0300 +++ b/src/imap/imap-fetch-body.c Tue Apr 26 13:43:54 2005 +0300 @@ -174,7 +174,7 @@ } if ((uoff_t)sent != virtual_size && !blocks) { - /* Input stream gave less data then we expected. Two choices + /* Input stream gave less data than we expected. Two choices here: either we fill the missing data with spaces or we disconnect the client.
--- a/src/lib/ostream-crlf.c Tue Apr 26 12:42:59 2005 +0300 +++ b/src/lib/ostream-crlf.c Tue Apr 26 13:43:54 2005 +0300 @@ -55,6 +55,13 @@ return o_stream_flush(cstream->output); } +static void _flush_pending(struct _ostream *stream, int set) +{ + struct crlf_ostream *cstream = (struct crlf_ostream *)stream; + + o_stream_set_flush_pending(cstream->output, set); +} + static size_t _get_used_size(struct _ostream *stream) { struct crlf_ostream *cstream = (struct crlf_ostream *)stream; @@ -352,6 +359,7 @@ cstream->ostream.cork = _cork; cstream->ostream.flush = _flush; + cstream->ostream.flush_pending = _flush_pending; cstream->ostream.get_used_size = _get_used_size; cstream->ostream.seek = _seek; cstream->ostream.send_istream = _send_istream;
--- a/src/lib/ostream-file.c Tue Apr 26 12:42:59 2005 +0300 +++ b/src/lib/ostream-file.c Tue Apr 26 13:43:54 2005 +0300 @@ -45,6 +45,7 @@ unsigned int full:1; /* if head == tail, is buffer empty or full? */ unsigned int file:1; unsigned int corked:1; + unsigned int flush_pending:1; unsigned int no_socket_cork:1; unsigned int no_sendfile:1; unsigned int autoclose_fd:1; @@ -226,10 +227,12 @@ if (set && fstream->io != NULL) { io_remove(fstream->io); fstream->io = NULL; - } else if (!set && fstream->io == NULL) { + } else if (!set) { if (fstream->file) buffer_flush(fstream); - else { + else if (fstream->io == NULL && + (!IS_STREAM_EMPTY(fstream) || + fstream->flush_pending)) { fstream->io = io_add(fstream->fd, IO_WRITE, stream_send_io, fstream); } @@ -244,6 +247,17 @@ return buffer_flush(fstream); } +static void _flush_pending(struct _ostream *stream, int set) +{ + struct file_ostream *fstream = (struct file_ostream *) stream; + + fstream->flush_pending = set; + if (set && !fstream->corked && fstream->io == NULL) { + fstream->io = io_add(fstream->fd, IO_WRITE, + stream_send_io, fstream); + } +} + static size_t get_unused_space(struct file_ostream *fstream) { if (fstream->head > fstream->tail) { @@ -347,6 +361,8 @@ io_remove(fstream->io); fstream->io = NULL; } + fstream->flush_pending = ret <= 0; + o_stream_unref(&fstream->ostream.ostream); } @@ -711,6 +727,7 @@ fstream->ostream.cork = _cork; fstream->ostream.flush = _flush; + fstream->ostream.flush_pending = _flush_pending; fstream->ostream.get_used_size = _get_used_size; fstream->ostream.seek = _seek; fstream->ostream.sendv = _sendv;
--- a/src/lib/ostream-internal.h Tue Apr 26 12:42:59 2005 +0300 +++ b/src/lib/ostream-internal.h Tue Apr 26 13:43:54 2005 +0300 @@ -11,6 +11,7 @@ /* methods: */ void (*cork)(struct _ostream *stream, int set); int (*flush)(struct _ostream *stream); + void (*flush_pending)(struct _ostream *stream, int set); size_t (*get_used_size)(struct _ostream *stream); int (*seek)(struct _ostream *stream, uoff_t offset); ssize_t (*sendv)(struct _ostream *stream, const struct const_iovec *iov,
--- a/src/lib/ostream.c Tue Apr 26 12:42:59 2005 +0300 +++ b/src/lib/ostream.c Tue Apr 26 13:43:54 2005 +0300 @@ -66,6 +66,13 @@ return _stream->flush(_stream); } +void o_stream_set_flush_pending(struct ostream *stream, int set) +{ + struct _ostream *_stream = stream->real_stream; + + _stream->flush_pending(_stream, set); +} + size_t o_stream_get_buffer_used_size(struct ostream *stream) { struct _ostream *_stream = stream->real_stream;
--- a/src/lib/ostream.h Tue Apr 26 12:42:59 2005 +0300 +++ b/src/lib/ostream.h Tue Apr 26 13:43:54 2005 +0300 @@ -46,6 +46,9 @@ /* Flush the output stream, blocks until everything is sent. Returns 1 if ok, -1 if error. */ int o_stream_flush(struct ostream *stream); +/* Set "flush pending" state of stream. If set, the flush callback is called + when more data is allowed to be sent, even if the buffer itself is empty. */ +void o_stream_set_flush_pending(struct ostream *stream, int set); /* Returns number of bytes currently in buffer. */ size_t o_stream_get_buffer_used_size(struct ostream *stream);
--- a/src/pop3/client.c Tue Apr 26 12:42:59 2005 +0300 +++ b/src/pop3/client.c Tue Apr 26 13:43:54 2005 +0300 @@ -310,6 +310,8 @@ if (client_command_execute(client, line, args)) { client->bad_counter = 0; if (client->cmd != NULL) { + o_stream_set_flush_pending(client->output, + TRUE); client->waiting_input = TRUE; break; }