Mercurial > dovecot > original-hg > dovecot-1.2
changeset 404:f25e575bf1ca HEAD
Created datastack_mempool which is used by at least a few temporary
IOBuffers. Some other minor speedups/cleanups in IOBuffer and elsewhere..
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 10 Oct 2002 05:01:34 +0300 |
parents | c3c7f9345f83 |
children | 576967cbd064 |
files | src/lib-index/maildir/maildir-build.c src/lib-index/maildir/maildir-index.h src/lib-index/maildir/maildir-open.c src/lib-index/maildir/maildir-sync.c src/lib-index/maildir/maildir-update.c src/lib-index/mbox/mbox-index.c src/lib-index/mbox/mbox-rewrite.c src/lib-storage/index/mbox/mbox-expunge.c src/lib/iobuffer.c src/lib/iobuffer.h src/lib/ioloop.c src/lib/mempool-datastack.c src/lib/network.c |
diffstat | 13 files changed, 324 insertions(+), 124 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/maildir/maildir-build.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib-index/maildir/maildir-build.c Thu Oct 10 05:01:34 2002 +0300 @@ -69,7 +69,7 @@ MAILDIR_LOCATION_EXTRA_SPACE); /* parse the header and update record's fields */ - failed = !maildir_record_update(update, fd, path); + failed = !maildir_record_update(update, fd, st.st_size); if (!index->update_end(update) || failed) return FALSE;
--- a/src/lib-index/maildir/maildir-index.h Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib-index/maildir/maildir-index.h Thu Oct 10 05:01:34 2002 +0300 @@ -22,6 +22,6 @@ IOBuffer *maildir_open_mail(MailIndex *index, MailIndexRecord *rec); -int maildir_record_update(MailIndexUpdate *update, int fd, const char *path); +int maildir_record_update(MailIndexUpdate *update, int fd, off_t file_size); #endif
--- a/src/lib-index/maildir/maildir-open.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib-index/maildir/maildir-open.c Thu Oct 10 05:01:34 2002 +0300 @@ -28,13 +28,12 @@ } path = t_strconcat(index->dir, "/cur/", fname, NULL); - fd = open(path, O_RDONLY); if (fd == -1) { index_set_error(index, "Error opening mail file %s: %m", path); return NULL; } - return io_buffer_create_mmap(fd, default_pool, MAIL_MMAP_BLOCK_SIZE, - 0, 0, TRUE); + return io_buffer_create_mmap(fd, default_pool, MAIL_MMAP_BLOCK_SIZE, 0, + 0, IOBUFFER_FLAG_AUTOCLOSE); }
--- a/src/lib-index/maildir/maildir-sync.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib-index/maildir/maildir-sync.c Thu Oct 10 05:01:34 2002 +0300 @@ -14,9 +14,9 @@ #include <utime.h> #include <sys/stat.h> -static int maildir_index_sync_file(MailIndex *index, - MailIndexRecord *rec, unsigned int seq, - const char *fname, const char *path, +static int maildir_index_sync_file(MailIndex *index, MailIndexRecord *rec, + unsigned int seq, const char *fname, + const char *path, off_t file_size, int fname_changed, int file_changed) { MailIndexUpdate *update; @@ -41,7 +41,7 @@ index_file_set_syscall_error(index, path, "open()"); failed = TRUE; } else { - if (!maildir_record_update(update, fd, path)) + if (!maildir_record_update(update, fd, file_size)) failed = TRUE; if (close(fd) < 0) { index_file_set_syscall_error(index, path, @@ -124,7 +124,8 @@ fname_changed = strcmp(value, fname) != 0; if (fname_changed || file_changed) { if (!maildir_index_sync_file(index, rec, seq, value, - str, fname_changed, + str, st.st_size, + fname_changed, file_changed)) return FALSE; }
--- a/src/lib-index/maildir/maildir-update.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib-index/maildir/maildir-update.c Thu Oct 10 05:01:34 2002 +0300 @@ -4,15 +4,15 @@ #include "iobuffer.h" #include "maildir-index.h" -int maildir_record_update(MailIndexUpdate *update, int fd, const char *path) +int maildir_record_update(MailIndexUpdate *update, int fd, off_t file_size) { IOBuffer *inbuf; - i_assert(path != NULL); - - inbuf = io_buffer_create_mmap(fd, default_pool, - MAIL_MMAP_BLOCK_SIZE, 0, 0, FALSE); + t_push(); + inbuf = io_buffer_create_mmap(fd, data_stack_pool, + MAIL_MMAP_BLOCK_SIZE, 0, file_size, 0); mail_index_update_headers(update, inbuf, 0, NULL, NULL); io_buffer_unref(inbuf); + t_pop(); return TRUE; }
--- a/src/lib-index/mbox/mbox-index.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib-index/mbox/mbox-index.c Thu Oct 10 05:01:34 2002 +0300 @@ -39,7 +39,7 @@ return io_buffer_create_mmap(index->mbox_fd, default_pool, MAIL_MMAP_BLOCK_SIZE, - (uoff_t)offset, 0, FALSE); + (uoff_t)offset, 0, 0); } void mbox_file_close(MailIndex *index)
--- a/src/lib-index/mbox/mbox-rewrite.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib-index/mbox/mbox-rewrite.c Thu Oct 10 05:01:34 2002 +0300 @@ -362,8 +362,11 @@ if (lseek(out_fd, (off_t)out_offset, SEEK_SET) < 0) return -1; - inbuf = io_buffer_create_mmap(in_fd, default_pool, 65536, 0, 0, FALSE); - outbuf = io_buffer_create_file(out_fd, default_pool, 1024, FALSE); + t_push(); + + inbuf = io_buffer_create_mmap(in_fd, data_stack_pool, + 1024*256, 0, 0, 0); + outbuf = io_buffer_create_file(out_fd, data_stack_pool, 1024, FALSE); ret = io_buffer_send_iobuffer(outbuf, inbuf, inbuf->size); if (ret < 0) @@ -376,6 +379,7 @@ io_buffer_unref(outbuf); io_buffer_unref(inbuf); + t_pop(); return ret; } @@ -447,7 +451,8 @@ } dirty_offset = 0; - outbuf = io_buffer_create_file(tmp_fd, default_pool, 8192, FALSE); + t_push(); + outbuf = io_buffer_create_file(tmp_fd, data_stack_pool, 8192, FALSE); failed = FALSE; seq = 1; rec = index->lookup(index, 1); @@ -522,6 +527,7 @@ io_buffer_unref(inbuf); io_buffer_unref(outbuf); + t_pop(); if (!failed) { /* POSSIBLE DATA LOSS HERE. We're writing to the mbox file,
--- a/src/lib-storage/index/mbox/mbox-expunge.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib-storage/index/mbox/mbox-expunge.c Thu Oct 10 05:01:34 2002 +0300 @@ -126,7 +126,8 @@ return FALSE; } - outbuf = io_buffer_create_file(inbuf->fd, default_pool, 4096, FALSE); + t_push(); + outbuf = io_buffer_create_file(inbuf->fd, data_stack_pool, 4096, FALSE); failed = !expunge_real(ibox, rec, seq, inbuf, outbuf, expunge_func, context); @@ -148,6 +149,7 @@ (void)mbox_unlock(ibox->index); io_buffer_unref(outbuf); + t_pop(); return !failed; }
--- a/src/lib/iobuffer.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib/iobuffer.c Thu Oct 10 05:01:34 2002 +0300 @@ -31,6 +31,9 @@ #include "network.h" #include <unistd.h> +#include <sys/stat.h> + +#define IO_BUFFER_MIN_SIZE 4096 #define MAX_SSIZE_T(size) ((size) < SSIZE_T_MAX ? (size_t)(size) : SSIZE_T_MAX) @@ -57,6 +60,7 @@ i_assert(fd >= 0); i_assert(pool != NULL); + pool_ref(pool); buf = p_new(pool, IOBuffer, 1); buf->refcount = 1; buf->fd = fd; @@ -67,22 +71,22 @@ } IOBuffer *io_buffer_create_file(int fd, Pool pool, size_t max_buffer_size, - int autoclose_fd) + int flags) { IOBuffer *buf; buf = io_buffer_create(fd, pool, IO_PRIORITY_DEFAULT, max_buffer_size); buf->file = TRUE; - buf->close_file = autoclose_fd; + buf->close_file = (flags & IOBUFFER_FLAG_AUTOCLOSE) != 0; return buf; } IOBuffer *io_buffer_create_mmap(int fd, Pool pool, size_t block_size, - uoff_t start_offset, uoff_t size, - int autoclose_fd) + uoff_t start_offset, uoff_t size, int flags) { IOBuffer *buf; - off_t stop_offset; + struct stat st; + uoff_t stop_offset; i_assert(start_offset < OFF_T_MAX); @@ -99,30 +103,33 @@ block_size += mmap_pagesize; } - buf = io_buffer_create_file(fd, pool, block_size, autoclose_fd); + buf = io_buffer_create_file(fd, pool, block_size, flags); buf->mmaped = TRUE; buf->receive = TRUE; - stop_offset = lseek(fd, 0, SEEK_END); - if (stop_offset < 0) { + if (fstat(fd, &st) == 0) + stop_offset = (uoff_t)st.st_size; + else { i_error("io_buffer_create_mmap(): lseek() failed: %m"); stop_offset = 0; - buf->size = 0; } - if (start_offset > (uoff_t)stop_offset) + if (start_offset > stop_offset) start_offset = stop_offset; - if (size > (uoff_t)stop_offset-start_offset) { - i_warning("Trying to create IOBuffer with size %"PRIuUOFF_T - " but we have only %"PRIuUOFF_T" bytes available " - "in file", size, stop_offset-start_offset); + if (size > stop_offset-start_offset) { + i_warning("Trying to create IOBuffer with size " + "%"PRIuUOFF_T" but we have only %"PRIuUOFF_T + " bytes available in file", size, + stop_offset-start_offset); size = stop_offset-start_offset; } + if (size == 0) + size = stop_offset - start_offset; + buf->start_offset = start_offset; - buf->size = size > 0 ? size : stop_offset - start_offset; - buf->limit = buf->size; + buf->limit = buf->size = size; buf->skip = buf->pos = buf->start_offset; return buf; @@ -156,6 +163,7 @@ } io_buffer_close(buf); p_free(buf->pool, buf); + pool_unref(buf->pool); } void io_buffer_close(IOBuffer *buf) @@ -238,11 +246,6 @@ { ssize_t ret; - i_assert(size <= SSIZE_T_MAX); - - if (size == 0) - return 0; - ret = write(fd, buf, size); if (ret < 0 && (errno == EINTR || errno == EAGAIN)) ret = 0; @@ -250,38 +253,52 @@ return ret; } -static void buf_send_real(IOBuffer *buf) +static ssize_t io_buffer_write(IOBuffer *buf, const void *data, size_t size) { - int ret; + ssize_t ret; - if (!buf->file) { - ret = net_transmit(buf->fd, buf->buffer + buf->skip, - buf->pos - buf->skip); - } else { - ret = my_write(buf->fd, buf->buffer + buf->skip, - buf->pos - buf->skip); - } + if (size > SSIZE_T_MAX) + size = SSIZE_T_MAX; + if (size == 0) + return 0; + ret = buf->file ? my_write(buf->fd, data, size) : + net_transmit(buf->fd, data, size); if (ret < 0) { + /* disconnected */ buf->buf_errno = errno; io_buffer_close(buf); - } else { - buf->offset += ret; - buf->skip += ret; - if (buf->skip == buf->pos) { - /* everything sent */ - buf->skip = buf->pos = 0; + return -1; + } + + buf->offset += ret; + return ret; +} + +static void buf_send_real(IOBuffer *buf) +{ + ssize_t ret; + + ret = io_buffer_write(buf, buf->buffer + buf->skip, + buf->pos - buf->skip); + if (ret < 0) + return; - /* call flush function */ - if (buf->flush_func != NULL) { - buf->flush_func(buf->flush_context, buf); - buf->flush_func = NULL; + buf->skip += ret; + if (buf->skip == buf->pos) { + /* everything sent */ + buf->skip = buf->pos = 0; - if (buf->corked) { - /* remove cork */ + /* call flush function */ + if (buf->flush_func != NULL) { + buf->flush_func(buf->flush_context, buf); + buf->flush_func = NULL; + + if (buf->corked) { + /* remove cork */ + if (!buf->file) net_set_cork(buf->fd, FALSE); - buf->corked = FALSE; - } + buf->corked = FALSE; } } } @@ -300,32 +317,56 @@ return TRUE; } +#define IOBUFFER_IS_FULL(buf) \ + ((buf)->pos == (buf)->buffer_size) + +/* write only as much as needed, put the rest into buffer. + write() only full buffers. */ static void block_loop_send(IOBufferBlockContext *ctx) { - size_t size; + size_t size, buffer_space_left; ssize_t ret; - if (ctx->outbuf->skip != ctx->outbuf->pos) { - buf_send_real(ctx->outbuf); - } else { - /* send the data */ - size = MAX_SSIZE_T(ctx->size); + size = MAX_SSIZE_T(ctx->size); + + buffer_space_left = ctx->outbuf->buffer_size - ctx->outbuf->pos; + if (ctx->outbuf->pos != 0 || ctx->size < buffer_space_left) { + if (buffer_space_left > 0) { + /* we have space in the buffer, fill it before + writing */ + if (size > buffer_space_left) + size = buffer_space_left; - ret = !ctx->outbuf->file ? - net_transmit(ctx->outbuf->fd, ctx->data, size) : - my_write(ctx->outbuf->fd, ctx->data, size); + memcpy(ctx->outbuf->buffer + ctx->outbuf->pos, + ctx->data, size); + ctx->outbuf->pos += size; - if (ret < 0) { - ctx->outbuf->buf_errno = errno; - io_buffer_close(ctx->outbuf); - } else { - ctx->outbuf->offset += ret; + ctx->data += size; + ctx->size -= size; + } + + if (IOBUFFER_IS_FULL(ctx->outbuf)) + buf_send_real(ctx->outbuf); + } else { + ret = io_buffer_write(ctx->outbuf, ctx->data, size); + if (ret > 0) { ctx->data += ret; ctx->size -= ret; } } - if (ctx->outbuf->closed || (ctx->size == 0 && ctx->last_block)) + if (ctx->outbuf->closed || (ctx->size == 0 && ctx->last_block && + !IOBUFFER_IS_FULL(ctx->outbuf))) + io_loop_stop(ctx->ioloop); +} + +/* write out all data from buffer */ +static void block_loop_flush(IOBufferBlockContext *ctx) +{ + if (ctx->outbuf->skip != ctx->outbuf->pos) + buf_send_real(ctx->outbuf); + + if (ctx->outbuf->closed || ctx->outbuf->skip == ctx->outbuf->pos) io_loop_stop(ctx->ioloop); } @@ -342,7 +383,6 @@ static int io_buffer_ioloop(IOBuffer *buf, IOBufferBlockContext *ctx, void (*send_func)(IOBufferBlockContext *ctx)) { - Pool pool; Timeout to; int save_errno; @@ -350,9 +390,10 @@ if (buf->io != NULL) io_remove(buf->io); + t_push(); + /* create a new I/O loop */ - pool = pool_create("io_buffer_ioloop", 1024, FALSE); - ctx->ioloop = io_loop_create(pool); + ctx->ioloop = io_loop_create(data_stack_pool); ctx->outbuf = buf; buf->io = io_add(buf->fd, IO_WRITE, (IOFunc) send_func, ctx); @@ -362,12 +403,6 @@ io_loop_run(ctx->ioloop); save_errno = errno; - if (buf->corked) { - /* remove cork */ - net_set_cork(buf->fd, FALSE); - buf->corked = FALSE; - } - if (buf->io != NULL) { io_remove(buf->io); buf->io = NULL; @@ -382,7 +417,8 @@ } io_loop_destroy(ctx->ioloop); - pool_unref(pool); + + t_pop(); errno = save_errno; return ctx->size > 0 ? -1 : 1; @@ -402,13 +438,38 @@ return io_buffer_ioloop(buf, &ctx, block_loop_send); } +static int io_buffer_flush(IOBuffer *buf) +{ + IOBufferBlockContext ctx; + ssize_t ret; + + if (buf->skip == buf->pos) + return 1; + + ret = io_buffer_write(buf, buf->buffer + buf->skip, + buf->pos - buf->skip); + if (ret < 0) + return -1; + + buf->skip += ret; + if (buf->skip == buf->pos) + return 1; + + memset(&ctx, 0, sizeof(ctx)); + ctx.last_block = TRUE; + + return io_buffer_ioloop(buf, &ctx, block_loop_flush); +} + void io_buffer_cork(IOBuffer *buf) { i_assert(!buf->receive); - if (!buf->file && !buf->corked) - net_set_cork(buf->fd, TRUE); - buf->corked = TRUE; + if (!buf->corked) { + if (!buf->file) + net_set_cork(buf->fd, TRUE); + buf->corked = TRUE; + } } static void buffer_alloc_more(IOBuffer *buf, size_t size) @@ -446,7 +507,8 @@ int io_buffer_send(IOBuffer *buf, const void *data, size_t size) { - int i, corked, ret; + ssize_t ret; + int i, corked; i_assert(!buf->receive); i_assert(data != NULL); @@ -462,16 +524,10 @@ for (i = 0; i < 2; i++) { if (buf->pos == 0 && !corked) { /* buffer is empty, try to send the data immediately */ - ret = buf->file ? my_write(buf->fd, data, size) : - net_transmit(buf->fd, data, size); - if (ret < 0) { - /* disconnected */ - buf->buf_errno = errno; - io_buffer_close(buf); + ret = io_buffer_write(buf, data, size); + if (ret < 0) return -1; - } - buf->offset += ret; data = (const char *) data + ret; size -= ret; } @@ -501,7 +557,7 @@ memcpy(buf->buffer + buf->pos, data, size); buf->pos += size; - if (buf->io == NULL) { + if (buf->io == NULL && !buf->corked) { buf->io = io_add_priority(buf->fd, buf->priority, IO_WRITE, (IOFunc) buf_send, buf); } @@ -543,7 +599,9 @@ i_assert(inbuf->offset < OFF_T_MAX); - io_buffer_send_flush(outbuf); + /* flush out any data in buffer */ + if (io_buffer_flush(outbuf) < 0) + return -1; /* first try if we can do it with a single sendfile() call */ offset = inbuf->offset; @@ -636,15 +694,15 @@ { i_assert(!buf->receive); - if (buf->closed || buf->io == NULL) + if (buf->closed) return; - if (buf->skip != buf->pos) - io_buffer_send_blocking(buf, NULL, 0); + io_buffer_flush(buf); if (buf->corked) { /* remove cork */ - net_set_cork(buf->fd, FALSE); + if (!buf->file) + net_set_cork(buf->fd, FALSE); buf->corked = FALSE; } } @@ -661,6 +719,12 @@ buf->flush_func = func; buf->flush_context = context; + + /* if we're corked, the io wasn't set */ + if (buf->io == NULL) { + buf->io = io_add_priority(buf->fd, buf->priority, IO_WRITE, + (IOFunc) buf_send, buf); + } } static ssize_t io_buffer_set_mmaped_pos(IOBuffer *buf) @@ -721,7 +785,11 @@ return -1; } - (void)madvise((void *) buf->buffer, buf->buffer_size, MADV_SEQUENTIAL); + /* madvise() only if the mmap()ed area was larger than page size */ + if (buf->buffer_size > mmap_pagesize) { + (void)madvise((void *) buf->buffer, buf->buffer_size, + MADV_SEQUENTIAL); + } return io_buffer_set_mmaped_pos(buf); } @@ -1064,16 +1132,10 @@ if (buf->pos == 0 && !buf->corked) { /* buffer is empty, try to send the data immediately */ - ret = buf->file ? my_write(buf->fd, buf->buffer, size) : - net_transmit(buf->fd, buf->buffer, size); - if (ret < 0) { - /* disconnected */ - buf->buf_errno = errno; - io_buffer_close(buf); + ret = io_buffer_write(buf, buf->buffer, size); + if (ret < 0) return -1; - } - buf->offset += ret; if ((size_t)ret == size) { /* all sent */ return 1; @@ -1084,7 +1146,7 @@ buf->pos += size; - if (buf->io == NULL) { + if (buf->io == NULL && !buf->corked) { buf->io = io_add_priority(buf->fd, buf->priority, IO_WRITE, (IOFunc) buf_send, buf); }
--- a/src/lib/iobuffer.h Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib/iobuffer.h Thu Oct 10 05:01:34 2002 +0300 @@ -3,9 +3,11 @@ #include "ioloop.h" -#define IO_BUFFER_MIN_SIZE 512 +typedef void (*IOBufferFlushFunc) (void *context, IOBuffer *buf); -typedef void (*IOBufferFlushFunc) (void *context, IOBuffer *buf); +enum { + IOBUFFER_FLAG_AUTOCLOSE = 0x01 +}; struct _IOBuffer { int fd; @@ -52,12 +54,12 @@ size_t max_buffer_size); /* Same as io_buffer_create(), but specify that we're reading/writing file. */ IOBuffer *io_buffer_create_file(int fd, Pool pool, size_t max_buffer_size, - int autoclose_fd); + int flags); /* Read the file by mmap()ing it in blocks. stop_offset specifies where to stop reading, or 0 to end of file. */ IOBuffer *io_buffer_create_mmap(int fd, Pool pool, size_t block_size, uoff_t start_offset, uoff_t size, - int autoclose_fd); + int flags); /* Reference counting. References start from 1, so calling io_buffer_unref() destroys the buffer if io_buffer_ref() is never used. */
--- a/src/lib/ioloop.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib/ioloop.c Thu Oct 10 05:01:34 2002 +0300 @@ -35,7 +35,7 @@ ((tvp)->tv_sec == (uvp)->tv_sec && \ (tvp)->tv_usec > (uvp)->tv_usec)) -time_t ioloop_time; +time_t ioloop_time = 0; struct timeval ioloop_timeval; static IOLoop current_ioloop = NULL; @@ -192,7 +192,8 @@ timeout->func = func; timeout->context = context; - timeout_update_next(timeout, NULL); + timeout_update_next(timeout, current_ioloop->running ? + NULL : &ioloop_timeval); timeout_list_insert(current_ioloop, timeout); return timeout; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/mempool-datastack.c Thu Oct 10 05:01:34 2002 +0300 @@ -0,0 +1,126 @@ +/* + mempool-data-stack.c : Memory pool wrapper for data stack + + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "mempool.h" + +#include <stdlib.h> + +#define MAX_ALLOC_SIZE SSIZE_T_MAX + +typedef struct { + union { + size_t size; + unsigned char alignment[MEM_ALIGN_SIZE]; + } size; + /* void data[]; */ +} PoolAlloc; + +static void pool_data_stack_ref(Pool pool); +static void pool_data_stack_unref(Pool pool); +static void *pool_data_stack_malloc(Pool pool, size_t size); +static void pool_data_stack_free(Pool pool, void *mem); +static void *pool_data_stack_realloc(Pool pool, void *mem, size_t size); +static void *pool_data_stack_realloc_min(Pool pool, void *mem, size_t size); +static void pool_data_stack_clear(Pool pool); + +static struct Pool static_data_stack_pool = { + pool_data_stack_ref, + pool_data_stack_unref, + + pool_data_stack_malloc, + pool_data_stack_free, + + pool_data_stack_realloc, + pool_data_stack_realloc_min, + + pool_data_stack_clear +}; + +Pool data_stack_pool = &static_data_stack_pool; + +static void pool_data_stack_ref(Pool pool __attr_unused__) +{ +} + +static void pool_data_stack_unref(Pool pool __attr_unused__) +{ +} + +static void *pool_data_stack_malloc(Pool pool __attr_unused__, size_t size) +{ + PoolAlloc *alloc; + + if (size > MAX_ALLOC_SIZE) + i_panic("Trying to allocate too much memory"); + + alloc = t_malloc0(sizeof(PoolAlloc) + size); + alloc->size.size = size; + + return (char *) alloc + sizeof(PoolAlloc); +} + +static void pool_data_stack_free(Pool pool __attr_unused__, + void *mem __attr_unused__) +{ +} + +static void *pool_data_stack_realloc(Pool pool, void *mem, size_t size) +{ + return pool_data_stack_realloc_min(pool, mem, size); +} + +static void *pool_data_stack_realloc_min(Pool pool __attr_unused__, + void *mem, size_t size) +{ + PoolAlloc *alloc, *new_alloc; + size_t old_size; + unsigned char *rmem; + + if (mem == NULL) + return pool_data_stack_malloc(pool, size); + + /* get old size */ + alloc = (PoolAlloc *) ((char *) mem - sizeof(PoolAlloc)); + old_size = alloc->size.size; + + if (old_size >= size) + return mem; + + if (!t_try_realloc(alloc, sizeof(PoolAlloc) + size)) { + new_alloc = t_malloc(sizeof(PoolAlloc) + size); + memcpy(new_alloc, alloc, old_size + sizeof(PoolAlloc)); + alloc = new_alloc; + } + alloc->size.size = size; + + rmem = (unsigned char *) alloc + sizeof(PoolAlloc); + memset(rmem + old_size, 0, size-old_size); + return rmem; +} + +static void pool_data_stack_clear(Pool pool __attr_unused__) +{ +}
--- a/src/lib/network.c Thu Oct 10 04:45:42 2002 +0300 +++ b/src/lib/network.c Thu Oct 10 05:01:34 2002 +0300 @@ -228,7 +228,8 @@ void net_set_cork(int fd __attr_unused__, int cork __attr_unused__) { #ifdef TCP_CORK - setsockopt(fd, SOL_TCP, TCP_CORK, &cork, sizeof(cork)); + if (setsockopt(fd, SOL_TCP, TCP_CORK, &cork, sizeof(cork)) < 0) + i_error("setsockopt(TCP_CORK) failed: %m"); #endif }