Mercurial > dovecot > core-2.2
changeset 16236:81d87e43e167
istream API change: Added support for multiple destroy callbacks.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 07 Apr 2013 23:17:37 +0300 |
parents | f00cc6d783cf |
children | 73bef641620d |
files | src/lib-http/http-client-connection.c src/lib-imap-urlauth/imap-urlauth-connection.c src/lib-storage/index/index-mail.c src/lib/iostream-private.h src/lib/iostream-temp.c src/lib/iostream.c src/lib/istream.c src/lib/istream.h src/lib/json-parser.c |
diffstat | 9 files changed, 50 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-http/http-client-connection.c Sun Apr 07 22:55:42 2013 +0300 +++ b/src/lib-http/http-client-connection.c Sun Apr 07 23:17:37 2013 +0300 @@ -370,7 +370,7 @@ actual payload stream. */ conn->incoming_payload = response->payload = i_stream_create_limit(response->payload, (uoff_t)-1); - i_stream_set_destroy_callback(response->payload, + i_stream_add_destroy_callback(response->payload, http_client_payload_destroyed, req); /* the callback may add its own I/O, so we need to remove @@ -391,7 +391,8 @@ if (retrying) { /* retrying, don't destroy the request */ if (response->payload != NULL) { - i_stream_unset_destroy_callback(conn->incoming_payload); + i_stream_remove_destroy_callback(conn->incoming_payload, + http_client_payload_destroyed); i_stream_unref(&conn->incoming_payload); conn->conn.io = io_add(conn->conn.fd_in, IO_READ, http_client_connection_input,
--- a/src/lib-imap-urlauth/imap-urlauth-connection.c Sun Apr 07 22:55:42 2013 +0300 +++ b/src/lib-imap-urlauth/imap-urlauth-connection.c Sun Apr 07 23:17:37 2013 +0300 @@ -604,7 +604,7 @@ data = buffer_get_data(conn->literal_buf, &size); i_assert(size == conn->literal_size); reply->input = i_stream_create_from_data(data, size); - i_stream_set_destroy_callback(reply->input, + i_stream_add_destroy_callback(reply->input, literal_stream_destroy, conn->literal_buf); }
--- a/src/lib-storage/index/index-mail.c Sun Apr 07 22:55:42 2013 +0300 +++ b/src/lib-storage/index/index-mail.c Sun Apr 07 23:17:37 2013 +0300 @@ -948,7 +948,7 @@ /* do this only once in case a plugin changes the stream. otherwise the check would break. */ data->destroy_callback_set = TRUE; - i_stream_set_destroy_callback(data->stream, + i_stream_add_destroy_callback(data->stream, index_mail_stream_destroy_callback, mail); } @@ -1260,11 +1260,12 @@ i_stream_unref(&data->filter_stream); if (data->stream != NULL) { data->destroying_stream = TRUE; - if (!closing) { + if (!closing && data->destroy_callback_set) { /* we're replacing the stream with a new one. it's allowed to have references until the mail is closed (but we can't really check that) */ - i_stream_unset_destroy_callback(data->stream); + i_stream_remove_destroy_callback(data->stream, + index_mail_stream_destroy_callback); } i_stream_unref(&data->stream); if (closing) {
--- a/src/lib/iostream-private.h Sun Apr 07 22:55:42 2013 +0300 +++ b/src/lib/iostream-private.h Sun Apr 07 23:17:37 2013 +0300 @@ -3,6 +3,11 @@ /* This file is private to input stream and output stream implementations */ +struct iostream_destroy_callback { + void (*callback)(void *context); + void *context; +}; + struct iostream_private { int refcount; char *name; @@ -12,8 +17,7 @@ void (*set_max_buffer_size)(struct iostream_private *stream, size_t max_size); - void (*destroy_callback)(void *context); - void *destroy_context; + ARRAY(struct iostream_destroy_callback) destroy_callbacks; }; void io_stream_init(struct iostream_private *stream);
--- a/src/lib/iostream-temp.c Sun Apr 07 22:55:42 2013 +0300 +++ b/src/lib/iostream-temp.c Sun Apr 07 23:17:37 2013 +0300 @@ -253,7 +253,7 @@ tstream->buf->used); i_stream_set_name(input, t_strdup_printf( "(Temp file in %s)", tstream->temp_path_prefix)); - i_stream_set_destroy_callback(input, iostream_temp_buf_destroyed, + i_stream_add_destroy_callback(input, iostream_temp_buf_destroyed, tstream->buf); tstream->buf = NULL; }
--- a/src/lib/iostream.c Sun Apr 07 22:55:42 2013 +0300 +++ b/src/lib/iostream.c Sun Apr 07 23:17:37 2013 +0300 @@ -1,6 +1,7 @@ /* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "array.h" #include "iostream-private.h" static void @@ -31,14 +32,19 @@ void io_stream_unref(struct iostream_private *stream) { + const struct iostream_destroy_callback *dc; + i_assert(stream->refcount > 0); if (--stream->refcount != 0) return; stream->close(stream, FALSE); stream->destroy(stream); - if (stream->destroy_callback != NULL) - stream->destroy_callback(stream->destroy_context); + if (array_is_created(&stream->destroy_callbacks)) { + array_foreach(&stream->destroy_callbacks, dc) + dc->callback(dc->context); + array_free(&stream->destroy_callbacks); + } i_free(stream->name); i_free(stream);
--- a/src/lib/istream.c Sun Apr 07 22:55:42 2013 +0300 +++ b/src/lib/istream.c Sun Apr 07 23:17:37 2013 +0300 @@ -2,6 +2,7 @@ #include "lib.h" #include "ioloop.h" +#include "array.h" #include "str.h" #include "istream-private.h" @@ -53,22 +54,35 @@ *stream = NULL; } -#undef i_stream_set_destroy_callback -void i_stream_set_destroy_callback(struct istream *stream, +#undef i_stream_add_destroy_callback +void i_stream_add_destroy_callback(struct istream *stream, istream_callback_t *callback, void *context) { struct iostream_private *iostream = &stream->real_stream->iostream; + struct iostream_destroy_callback *dc; - iostream->destroy_callback = callback; - iostream->destroy_context = context; + if (!array_is_created(&iostream->destroy_callbacks)) + i_array_init(&iostream->destroy_callbacks, 2); + dc = array_append_space(&iostream->destroy_callbacks); + dc->callback = callback; + dc->context = context; } -void i_stream_unset_destroy_callback(struct istream *stream) +void i_stream_remove_destroy_callback(struct istream *stream, + void (*callback)()) { struct iostream_private *iostream = &stream->real_stream->iostream; + const struct iostream_destroy_callback *dcs; + unsigned int i, count; - iostream->destroy_callback = NULL; - iostream->destroy_context = NULL; + dcs = array_get(&iostream->destroy_callbacks, &count); + for (i = 0; i < count; i++) { + if (dcs[i].callback == callback) { + array_delete(&iostream->destroy_callbacks, i, 1); + return; + } + } + i_unreached(); } int i_stream_get_fd(struct istream *stream)
--- a/src/lib/istream.h Sun Apr 07 22:55:42 2013 +0300 +++ b/src/lib/istream.h Sun Apr 07 23:17:37 2013 +0300 @@ -52,15 +52,16 @@ /* Unreferences the stream and sets stream pointer to NULL. */ void i_stream_unref(struct istream **stream); /* Call the given callback function when stream is destroyed. */ -void i_stream_set_destroy_callback(struct istream *stream, +void i_stream_add_destroy_callback(struct istream *stream, istream_callback_t *callback, void *context) ATTR_NULL(3); -#define i_stream_set_destroy_callback(stream, callback, context) \ - i_stream_set_destroy_callback(stream + \ +#define i_stream_add_destroy_callback(stream, callback, context) \ + i_stream_add_destroy_callback(stream + \ CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ (istream_callback_t *)callback, context) /* Remove the destroy callback. */ -void i_stream_unset_destroy_callback(struct istream *stream); +void i_stream_remove_destroy_callback(struct istream *stream, + void (*callback)()); /* Return file descriptor for stream, or -1 if none is available. */ int i_stream_get_fd(struct istream *stream);
--- a/src/lib/json-parser.c Sun Apr 07 22:55:42 2013 +0300 +++ b/src/lib/json-parser.c Sun Apr 07 23:17:37 2013 +0300 @@ -596,7 +596,7 @@ parser->state = parser->state == JSON_STATE_OBJECT_VALUE ? JSON_STATE_OBJECT_SKIP_STRING : JSON_STATE_ARRAY_SKIP_STRING; parser->strinput = i_stream_create_jsonstr(parser->input); - i_stream_set_destroy_callback(parser->strinput, + i_stream_add_destroy_callback(parser->strinput, json_strinput_destroyed, parser); *input_r = parser->strinput;