dovecot-2.0: Transaction view: Don't assert-crash if record size...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Aug 14 01:33:26 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/3296870a8510
changeset: 9784:3296870a8510
user: Timo Sirainen <tss at iki.fi>
date: Thu Aug 13 18:33:18 2009 -0400
description:
Transaction view: Don't assert-crash if record size grows during transaction.
diffstat:
1 file changed, 19 insertions(+), 4 deletions(-)
src/lib-index/mail-index-transaction-view.c | 23 +++++++++++++++++++----
diffs (60 lines):
diff -r 252bb3d23fb9 -r 3296870a8510 src/lib-index/mail-index-transaction-view.c
--- a/src/lib-index/mail-index-transaction-view.c Thu Aug 13 14:17:57 2009 -0400
+++ b/src/lib-index/mail-index-transaction-view.c Thu Aug 13 18:33:18 2009 -0400
@@ -22,6 +22,7 @@ struct mail_index_view_transaction {
unsigned int record_size;
unsigned int recs_count;
void *recs;
+ ARRAY_DEFINE(all_recs, void *);
};
static void tview_close(struct mail_index_view *view)
@@ -29,12 +30,20 @@ static void tview_close(struct mail_inde
struct mail_index_view_transaction *tview =
(struct mail_index_view_transaction *)view;
struct mail_index_transaction *t = tview->t;
+ void **recs;
+ unsigned int i, count;
if (tview->lookup_map != NULL)
mail_index_unmap(&tview->lookup_map);
if (tview->lookup_return_data != NULL)
buffer_free(&tview->lookup_return_data);
- i_free(tview->recs);
+
+ if (array_is_created(&tview->all_recs)) {
+ recs = array_get_modifiable(&tview->all_recs, &count);
+ for (i = 0; i < count; i++)
+ i_free(recs[i]);
+ array_free(&tview->all_recs);
+ }
tview->super->close(view);
mail_index_transaction_unref(&t);
@@ -93,17 +102,23 @@ tview_apply_flag_updates(struct mail_ind
/* yes, we have flag updates. since we can't modify rec directly and
we want to be able to handle multiple mail_index_lookup() calls
without the second one overriding the first one's data, we'll
- create a records array and return data from there */
- if (tview->recs == NULL) {
+ create a records array and return data from there.
+
+ it's also possible that the record size increases, so we potentially
+ have to create multiple arrays. they all get eventually freed when
+ the view gets freed. */
+ if (map->hdr.record_size > tview->record_size) {
+ if (!array_is_created(&tview->all_recs))
+ i_array_init(&tview->all_recs, 4);
tview->recs_count = t->first_new_seq;
tview->record_size = I_MAX(map->hdr.record_size,
tview->view.map->hdr.record_size);
tview->recs = i_malloc(tview->record_size *
tview->recs_count);
+ array_append(&tview->all_recs, &tview->recs, 1);
}
i_assert(tview->recs_count == t->first_new_seq);
i_assert(seq > 0 && seq <= tview->recs_count);
- i_assert(map->hdr.record_size <= tview->record_size);
trec = PTR_OFFSET(tview->recs, (seq-1) * tview->record_size);
memcpy(trec, rec, map->hdr.record_size);
More information about the dovecot-cvs
mailing list