dovecot-2.2: istream API change: Added support for multiple dest...

dovecot at dovecot.org dovecot at dovecot.org
Sun Apr 7 23:26:58 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/81d87e43e167
changeset: 16236:81d87e43e167
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Apr 07 23:17:37 2013 +0300
description:
istream API change: Added support for multiple destroy callbacks.

diffstat:

 src/lib-http/http-client-connection.c          |   5 ++-
 src/lib-imap-urlauth/imap-urlauth-connection.c |   2 +-
 src/lib-storage/index/index-mail.c             |   7 +++--
 src/lib/iostream-private.h                     |   8 +++++-
 src/lib/iostream-temp.c                        |   2 +-
 src/lib/iostream.c                             |  10 +++++++-
 src/lib/istream.c                              |  28 +++++++++++++++++++------
 src/lib/istream.h                              |   9 ++++---
 src/lib/json-parser.c                          |   2 +-
 9 files changed, 50 insertions(+), 23 deletions(-)

diffs (221 lines):

diff -r f00cc6d783cf -r 81d87e43e167 src/lib-http/http-client-connection.c
--- 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,
diff -r f00cc6d783cf -r 81d87e43e167 src/lib-imap-urlauth/imap-urlauth-connection.c
--- 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);
 	}
diff -r f00cc6d783cf -r 81d87e43e167 src/lib-storage/index/index-mail.c
--- 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) {
diff -r f00cc6d783cf -r 81d87e43e167 src/lib/iostream-private.h
--- 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);
diff -r f00cc6d783cf -r 81d87e43e167 src/lib/iostream-temp.c
--- 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;
 	}
diff -r f00cc6d783cf -r 81d87e43e167 src/lib/iostream.c
--- 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);
diff -r f00cc6d783cf -r 81d87e43e167 src/lib/istream.c
--- 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)
diff -r f00cc6d783cf -r 81d87e43e167 src/lib/istream.h
--- 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);
diff -r f00cc6d783cf -r 81d87e43e167 src/lib/json-parser.c
--- 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;


More information about the dovecot-cvs mailing list