From: Timo Sirainen Date: Mon, 22 Jun 2009 21:45:56 +0000 (-0400) Subject: Added reference counting to struct mail_keywords and related APIs. X-Git-Tag: 2.0.alpha1~544 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=84ed9f8f3d0e5ed47607ef417618e49e4f865557;p=thirdparty%2Fdovecot%2Fcore.git Added reference counting to struct mail_keywords and related APIs. --HG-- branch : HEAD --- diff --git a/src/imap/cmd-append.c b/src/imap/cmd-append.c index a76aae9271..cec4ee9e1b 100644 --- a/src/imap/cmd-append.c +++ b/src/imap/cmd-append.c @@ -354,7 +354,7 @@ static bool cmd_append_continue_parsing(struct client_command_context *cmd) ret = mailbox_save_begin(&ctx->save_ctx, ctx->input); if (keywords != NULL) - mailbox_keywords_free(ctx->box, &keywords); + mailbox_keywords_unref(ctx->box, &keywords); if (ret < 0) { /* save initialization failed */ diff --git a/src/imap/cmd-copy.c b/src/imap/cmd-copy.c index 7969de2a24..d9fed38302 100644 --- a/src/imap/cmd-copy.c +++ b/src/imap/cmd-copy.c @@ -72,7 +72,8 @@ static int fetch_and_copy(struct client *client, struct mailbox *destbox, if (mailbox_copy(&save_ctx, mail) < 0) ret = mail->expunged ? 0 : -1; - mailbox_keywords_free(destbox, &keywords); + if (keywords != NULL) + mailbox_keywords_unref(destbox, &keywords); msgset_generator_next(&srcset_ctx, mail->uid); } diff --git a/src/imap/cmd-store.c b/src/imap/cmd-store.c index c021f86b1f..20a5caa3b7 100644 --- a/src/imap/cmd-store.c +++ b/src/imap/cmd-store.c @@ -198,7 +198,7 @@ bool cmd_store(struct client_command_context *cmd) mail_free(&mail); if (ctx.keywords != NULL) - mailbox_keywords_free(client->mailbox, &ctx.keywords); + mailbox_keywords_unref(client->mailbox, &ctx.keywords); ret = mailbox_search_deinit(&search_ctx); if (ret < 0) diff --git a/src/lib-index/mail-index-sync.c b/src/lib-index/mail-index-sync.c index b5b746c104..d6378705f2 100644 --- a/src/lib-index/mail-index-sync.c +++ b/src/lib-index/mail-index-sync.c @@ -89,7 +89,7 @@ static void mail_index_sync_add_keyword_update(struct mail_index_sync_ctx *ctx) } } - mail_index_keywords_free(&keywords); + mail_index_keywords_unref(&keywords); } static void mail_index_sync_add_keyword_reset(struct mail_index_sync_ctx *ctx) @@ -106,7 +106,7 @@ static void mail_index_sync_add_keyword_reset(struct mail_index_sync_ctx *ctx) MODIFY_REPLACE, keywords); } } - mail_index_keywords_free(&keywords); + mail_index_keywords_unref(&keywords); } static void mail_index_sync_add_append(struct mail_index_sync_ctx *ctx) diff --git a/src/lib-index/mail-index-transaction.c b/src/lib-index/mail-index-transaction.c index eafc3093cc..6a28d48408 100644 --- a/src/lib-index/mail-index-transaction.c +++ b/src/lib-index/mail-index-transaction.c @@ -1164,6 +1164,7 @@ mail_index_keywords_create(struct mail_index *index, if (count == 0) { k = i_new(struct mail_keywords, 1); k->index = index; + k->refcount = 1; return k; } @@ -1171,6 +1172,7 @@ mail_index_keywords_create(struct mail_index *index, k = i_malloc(sizeof(struct mail_keywords) + (sizeof(k->idx) * (count-1))); k->index = index; + k->refcount = 1; /* look up the keywords from index. they're never removed from there so we can permanently store indexes to them. */ @@ -1202,6 +1204,7 @@ mail_index_keywords_create_from_indexes(struct mail_index *index, if (count == 0) { k = i_new(struct mail_keywords, 1); k->index = index; + k->refcount = 1; return k; } @@ -1209,6 +1212,7 @@ mail_index_keywords_create_from_indexes(struct mail_index *index, k = i_malloc(sizeof(struct mail_keywords) + (sizeof(k->idx) * (count-1))); k->index = index; + k->refcount = 1; /* copy but skip duplicates */ for (src = dest = 0; src < count; src++) { @@ -1223,10 +1227,20 @@ mail_index_keywords_create_from_indexes(struct mail_index *index, return k; } -void mail_index_keywords_free(struct mail_keywords **keywords) +void mail_index_keywords_ref(struct mail_keywords *keywords) { - i_free(*keywords); - *keywords = NULL; + keywords->refcount++; +} + +void mail_index_keywords_unref(struct mail_keywords **_keywords) +{ + struct mail_keywords *keywords = *_keywords; + + i_assert(keywords->refcount > 0); + + *_keywords = NULL; + if (--keywords->refcount == 0) + i_free(keywords); } static bool diff --git a/src/lib-index/mail-index.h b/src/lib-index/mail-index.h index 03f80739a5..7d775d4e22 100644 --- a/src/lib-index/mail-index.h +++ b/src/lib-index/mail-index.h @@ -102,6 +102,7 @@ struct mail_index_record { struct mail_keywords { struct mail_index *index; unsigned int count; + int refcount; /* variable sized list of keyword indexes */ unsigned int idx[1]; @@ -430,8 +431,8 @@ struct mail_keywords * mail_index_keywords_create_from_indexes(struct mail_index *index, const ARRAY_TYPE(keyword_indexes) *keyword_indexes); -/* Free the keywords. */ -void mail_index_keywords_free(struct mail_keywords **keywords); +void mail_index_keywords_ref(struct mail_keywords *keywords); +void mail_index_keywords_unref(struct mail_keywords **keywords); /* Update keywords for given message. */ void mail_index_update_keywords(struct mail_index_transaction *t, uint32_t seq, diff --git a/src/lib-lda/mail-deliver.c b/src/lib-lda/mail-deliver.c index d5233aef29..5328b36fcb 100644 --- a/src/lib-lda/mail-deliver.c +++ b/src/lib-lda/mail-deliver.c @@ -183,7 +183,8 @@ int mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox, mailbox_save_set_flags(save_ctx, flags, kw); if (mailbox_copy(&save_ctx, ctx->src_mail) < 0) ret = -1; - mailbox_keywords_free(box, &kw); + if (kw != NULL) + mailbox_keywords_unref(box, &kw); if (ret < 0) mailbox_transaction_rollback(&t); diff --git a/src/lib-storage/index/cydir/cydir-storage.c b/src/lib-storage/index/cydir/cydir-storage.c index 02b22cf0cc..872598e74a 100644 --- a/src/lib-storage/index/cydir/cydir-storage.c +++ b/src/lib-storage/index/cydir/cydir-storage.c @@ -375,7 +375,8 @@ struct mailbox cydir_mailbox = { index_transaction_set_max_modseq, index_keywords_create, index_keywords_create_from_indexes, - index_keywords_free, + index_keywords_ref, + index_keywords_unref, index_keyword_is_valid, index_storage_get_seq_range, index_storage_get_uid_range, diff --git a/src/lib-storage/index/dbox/dbox-storage.c b/src/lib-storage/index/dbox/dbox-storage.c index ef05b3329f..11888241f4 100644 --- a/src/lib-storage/index/dbox/dbox-storage.c +++ b/src/lib-storage/index/dbox/dbox-storage.c @@ -878,7 +878,8 @@ struct mailbox dbox_mailbox = { index_transaction_set_max_modseq, index_keywords_create, index_keywords_create_from_indexes, - index_keywords_free, + index_keywords_ref, + index_keywords_unref, index_keyword_is_valid, index_storage_get_seq_range, index_storage_get_uid_range, diff --git a/src/lib-storage/index/dbox/dbox-sync-rebuild.c b/src/lib-storage/index/dbox/dbox-sync-rebuild.c index a6d1e05eb2..6c0c54b9aa 100644 --- a/src/lib-storage/index/dbox/dbox-sync-rebuild.c +++ b/src/lib-storage/index/dbox/dbox-sync-rebuild.c @@ -104,7 +104,7 @@ dbox_sync_index_copy_from_old(struct dbox_sync_rebuild_context *ctx, mail_index_lookup_keywords(view, old_seq, &old_keywords); kw = mail_index_keywords_create_from_indexes(index, &old_keywords); mail_index_update_keywords(ctx->trans, new_seq, MODIFY_REPLACE, kw); - mail_index_keywords_free(&kw); + mail_index_keywords_unref(&kw); dbox_sync_index_copy_cache(ctx, view, old_seq, new_seq); } @@ -125,7 +125,7 @@ dbox_sync_index_copy_from_maildir(struct dbox_sync_rebuild_context *ctx, keywords = mail_index_keywords_create_from_indexes(ctx->mbox->ibox.index, &keyword_indexes); mail_index_update_keywords(ctx->trans, seq, MODIFY_REPLACE, keywords); - mail_index_keywords_free(&keywords); + mail_index_keywords_unref(&keywords); } void dbox_sync_rebuild_index_metadata(struct dbox_sync_rebuild_context *ctx, diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 6564b96705..062ad63f89 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -644,9 +644,14 @@ index_keywords_create_from_indexes(struct mailbox *_box, return mail_index_keywords_create_from_indexes(ibox->index, idx); } -void index_keywords_free(struct mail_keywords *keywords) +void index_keywords_ref(struct mail_keywords *keywords) { - mail_index_keywords_free(&keywords); + mail_index_keywords_ref(keywords); +} + +void index_keywords_unref(struct mail_keywords *keywords) +{ + mail_index_keywords_unref(&keywords); } void index_save_context_free(struct mail_save_context *ctx) diff --git a/src/lib-storage/index/index-storage.h b/src/lib-storage/index/index-storage.h index 1d4c0660d9..d6c845e8eb 100644 --- a/src/lib-storage/index/index-storage.h +++ b/src/lib-storage/index/index-storage.h @@ -107,7 +107,8 @@ int index_keywords_create(struct mailbox *box, const char *const keywords[], struct mail_keywords * index_keywords_create_from_indexes(struct mailbox *box, const ARRAY_TYPE(keyword_indexes) *idx); -void index_keywords_free(struct mail_keywords *keywords); +void index_keywords_ref(struct mail_keywords *keywords); +void index_keywords_unref(struct mail_keywords *keywords); bool index_keyword_is_valid(struct mailbox *box, const char *keyword, const char **error_r); diff --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index 2da129f39d..c4ecb46012 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -1056,7 +1056,8 @@ struct mailbox maildir_mailbox = { index_transaction_set_max_modseq, index_keywords_create, index_keywords_create_from_indexes, - index_keywords_free, + index_keywords_ref, + index_keywords_unref, index_keyword_is_valid, index_storage_get_seq_range, index_storage_get_uid_range, diff --git a/src/lib-storage/index/maildir/maildir-sync-index.c b/src/lib-storage/index/maildir/maildir-sync-index.c index 97e090ebfc..e4cc230e4b 100644 --- a/src/lib-storage/index/maildir/maildir-sync-index.c +++ b/src/lib-storage/index/maildir/maildir-sync-index.c @@ -326,7 +326,7 @@ maildir_sync_mail_keywords(struct maildir_index_sync_context *ctx, uint32_t seq) kw = mail_index_keywords_create_from_indexes(mbox->ibox.index, &ctx->keywords); mail_index_update_keywords(ctx->trans, seq, MODIFY_REPLACE, kw); - mail_index_keywords_free(&kw); + mail_index_keywords_unref(&kw); return; } @@ -357,14 +357,14 @@ maildir_sync_mail_keywords(struct maildir_index_sync_context *ctx, uint32_t seq) kw = mail_index_keywords_create_from_indexes(mbox->ibox.index, &ctx->idx_keywords); mail_index_update_keywords(ctx->trans, seq, MODIFY_REMOVE, kw); - mail_index_keywords_free(&kw); + mail_index_keywords_unref(&kw); } if (array_count(&ctx->keywords) > 0) { kw = mail_index_keywords_create_from_indexes(mbox->ibox.index, &ctx->keywords); mail_index_update_keywords(ctx->trans, seq, MODIFY_ADD, kw); - mail_index_keywords_free(&kw); + mail_index_keywords_unref(&kw); } } @@ -464,7 +464,7 @@ int maildir_sync_index(struct maildir_index_sync_context *ctx, mbox->ibox.index, &ctx->keywords); mail_index_update_keywords(trans, seq, MODIFY_REPLACE, kw); - mail_index_keywords_free(&kw); + mail_index_keywords_unref(&kw); } continue; } diff --git a/src/lib-storage/index/mbox/mbox-storage.c b/src/lib-storage/index/mbox/mbox-storage.c index 00f3c59e8b..58464c3005 100644 --- a/src/lib-storage/index/mbox/mbox-storage.c +++ b/src/lib-storage/index/mbox/mbox-storage.c @@ -872,7 +872,8 @@ struct mailbox mbox_mailbox = { index_transaction_set_max_modseq, index_keywords_create, index_keywords_create_from_indexes, - index_keywords_free, + index_keywords_ref, + index_keywords_unref, index_keyword_is_valid, index_storage_get_seq_range, index_storage_get_uid_range, diff --git a/src/lib-storage/index/mbox/mbox-sync.c b/src/lib-storage/index/mbox/mbox-sync.c index 70bf80588f..6e268955bc 100644 --- a/src/lib-storage/index/mbox/mbox-sync.c +++ b/src/lib-storage/index/mbox/mbox-sync.c @@ -298,7 +298,7 @@ mbox_sync_update_index_keywords(struct mbox_sync_mail_context *mail_ctx) sync_ctx->mbox->ibox.index, &mail_ctx->mail.keywords); mail_index_update_keywords(sync_ctx->t, sync_ctx->idx_seq, MODIFY_REPLACE, keywords); - mail_index_keywords_free(&keywords); + mail_index_keywords_unref(&keywords); } static void diff --git a/src/lib-storage/index/raw/raw-storage.c b/src/lib-storage/index/raw/raw-storage.c index 22374432fa..db04876a77 100644 --- a/src/lib-storage/index/raw/raw-storage.c +++ b/src/lib-storage/index/raw/raw-storage.c @@ -215,7 +215,8 @@ struct mailbox raw_mailbox = { index_transaction_set_max_modseq, index_keywords_create, index_keywords_create_from_indexes, - index_keywords_free, + index_keywords_ref, + index_keywords_unref, index_keyword_is_valid, index_storage_get_seq_range, index_storage_get_uid_range, diff --git a/src/lib-storage/mail-search.c b/src/lib-storage/mail-search.c index 9b997170bb..7c5b1f159f 100644 --- a/src/lib-storage/mail-search.c +++ b/src/lib-storage/mail-search.c @@ -146,7 +146,7 @@ static void mail_search_args_deinit_sub(struct mail_search_args *args, case SEARCH_KEYWORDS: if (arg->value.keywords == NULL) break; - mailbox_keywords_free(args->box, &arg->value.keywords); + mailbox_keywords_unref(args->box, &arg->value.keywords); break; case SEARCH_INTHREAD: i_assert(arg->value.search_args->refcount > 0); @@ -534,8 +534,8 @@ mail_search_keywords_merge(struct mailbox *box, new_kw = mailbox_keywords_create_from_indexes(box, &new_indexes); } T_END; - mailbox_keywords_free(box, _kw1); - mailbox_keywords_free(box, _kw2); + mailbox_keywords_unref(box, _kw1); + mailbox_keywords_unref(box, _kw2); return new_kw; } diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 4ff4953bd0..d3ac3ea3f3 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -153,7 +153,8 @@ struct mailbox_vfuncs { struct mail_keywords * (*keywords_create_from_indexes)(struct mailbox *box, const ARRAY_TYPE(keyword_indexes) *idx); - void (*keywords_free)(struct mail_keywords *keywords); + void (*keywords_ref)(struct mail_keywords *keywords); + void (*keywords_unref)(struct mail_keywords *keywords); bool (*keyword_is_valid)(struct mailbox *box, const char *keyword, const char **error_r); diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 5c1588b41e..48fa1c4f33 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -658,13 +658,18 @@ mailbox_keywords_create_from_indexes(struct mailbox *box, return box->v.keywords_create_from_indexes(box, idx); } -void mailbox_keywords_free(struct mailbox *box, - struct mail_keywords **_keywords) +void mailbox_keywords_ref(struct mailbox *box, struct mail_keywords *keywords) +{ + box->v.keywords_ref(keywords); +} + +void mailbox_keywords_unref(struct mailbox *box, + struct mail_keywords **_keywords) { struct mail_keywords *keywords = *_keywords; *_keywords = NULL; - box->v.keywords_free(keywords); + box->v.keywords_unref(keywords); } bool mailbox_keyword_is_valid(struct mailbox *box, const char *keyword, diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index 14c92961f0..99fb0adec2 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -395,8 +395,9 @@ mailbox_keywords_create_valid(struct mailbox *box, struct mail_keywords * mailbox_keywords_create_from_indexes(struct mailbox *box, const ARRAY_TYPE(keyword_indexes) *idx); -void mailbox_keywords_free(struct mailbox *box, - struct mail_keywords **keywords); +void mailbox_keywords_ref(struct mailbox *box, struct mail_keywords *keywords); +void mailbox_keywords_unref(struct mailbox *box, + struct mail_keywords **keywords); /* Returns TRUE if keyword is valid, FALSE and error if not. */ bool mailbox_keyword_is_valid(struct mailbox *box, const char *keyword, const char **error_r); diff --git a/src/lib-storage/test-mailbox.c b/src/lib-storage/test-mailbox.c index 243654c63f..0d3614f2ef 100644 --- a/src/lib-storage/test-mailbox.c +++ b/src/lib-storage/test-mailbox.c @@ -120,6 +120,7 @@ test_mailbox_keywords_create(struct mailbox *box ATTR_UNUSED, bool skip_invalid ATTR_UNUSED) { *keywords_r = i_new(struct mail_keywords, 1); + (*keywords_r)->refcount = 1; return 0; } @@ -127,12 +128,22 @@ static struct mail_keywords * test_mailbox_keywords_create_from_indexes(struct mailbox *box ATTR_UNUSED, const ARRAY_TYPE(keyword_indexes) *idx ATTR_UNUSED) { - return i_new(struct mail_keywords, 1); + struct mail_keywords *keywords; + + keywords = i_new(struct mail_keywords, 1); + keywords->refcount++; + return keywords; +} + +static void test_mailbox_keywords_ref(struct mail_keywords *keywords) +{ + keywords->refcount++; } -static void test_mailbox_keywords_free(struct mail_keywords *keywords) +static void test_mailbox_keywords_unref(struct mail_keywords *keywords) { - i_free(keywords); + if (--keywords->refcount == 0) + i_free(keywords); } static bool @@ -297,7 +308,8 @@ struct mailbox test_mailbox = { test_mailbox_transaction_set_max_modseq, test_mailbox_keywords_create, test_mailbox_keywords_create_from_indexes, - test_mailbox_keywords_free, + test_mailbox_keywords_ref, + test_mailbox_keywords_unref, test_mailbox_keyword_is_valid, test_mailbox_get_seq_range, test_mailbox_get_uid_range, diff --git a/src/plugins/convert/convert-storage.c b/src/plugins/convert/convert-storage.c index ece802a3fb..9c337475ca 100644 --- a/src/plugins/convert/convert-storage.c +++ b/src/plugins/convert/convert-storage.c @@ -77,7 +77,8 @@ static int mailbox_copy_mails(struct mailbox *srcbox, struct mailbox *destbox, mailbox_save_set_flags(save_ctx, mail_get_flags(mail), keywords); ret = mailbox_copy(&save_ctx, mail); - mailbox_keywords_free(destbox, &keywords); + if (keywords != NULL) + mailbox_keywords_unref(destbox, &keywords); if (ret < 0) { *error_r = storage_error(destbox->storage); break; diff --git a/src/plugins/lazy-expunge/lazy-expunge-plugin.c b/src/plugins/lazy-expunge/lazy-expunge-plugin.c index 84623b4378..a823ee3bc8 100644 --- a/src/plugins/lazy-expunge/lazy-expunge-plugin.c +++ b/src/plugins/lazy-expunge/lazy-expunge-plugin.c @@ -166,7 +166,8 @@ static void lazy_expunge_mail_expunge(struct mail *_mail) if (mailbox_copy(&save_ctx, _mail) < 0 && !_mail->expunged) lt->failed = TRUE; - mailbox_keywords_free(lt->dest_box, &keywords); + if (keywords != NULL) + mailbox_keywords_unref(lt->dest_box, &keywords); mmail->super.expunge(_mail); } diff --git a/src/plugins/virtual/virtual-storage.c b/src/plugins/virtual/virtual-storage.c index 4bb8fbe4f5..12893d828e 100644 --- a/src/plugins/virtual/virtual-storage.c +++ b/src/plugins/virtual/virtual-storage.c @@ -588,7 +588,8 @@ struct mailbox virtual_mailbox = { index_transaction_set_max_modseq, index_keywords_create, index_keywords_create_from_indexes, - index_keywords_free, + index_keywords_ref, + index_keywords_unref, index_keyword_is_valid, index_storage_get_seq_range, index_storage_get_uid_range, diff --git a/src/plugins/virtual/virtual-sync.c b/src/plugins/virtual/virtual-sync.c index 538a49e78d..e34fd5ef40 100644 --- a/src/plugins/virtual/virtual-sync.c +++ b/src/plugins/virtual/virtual-sync.c @@ -76,7 +76,7 @@ static void virtual_sync_external_flags(struct virtual_sync_context *ctx, kw_names = mail_get_keywords(bbox->sync_mail); keywords = mail_index_keywords_create(ctx->index, kw_names); mail_index_update_keywords(ctx->trans, vseq, MODIFY_REPLACE, keywords); - mail_index_keywords_free(&keywords); + mail_index_keywords_unref(&keywords); } static int virtual_sync_mail_cmp(const void *p1, const void *p2) @@ -380,7 +380,7 @@ static void virtual_sync_index_rec(struct virtual_sync_context *ctx, MODIFY_ADD : MODIFY_REMOVE; mail_update_keywords(bbox->sync_mail, modify_type, keywords); - mailbox_keywords_free(bbox->box, &keywords); + mailbox_keywords_unref(bbox->box, &keywords); break; case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET: kw_names[0] = NULL; @@ -388,7 +388,7 @@ static void virtual_sync_index_rec(struct virtual_sync_context *ctx, kw_names); mail_update_keywords(bbox->sync_mail, MODIFY_REPLACE, keywords); - mailbox_keywords_free(bbox->box, &keywords); + mailbox_keywords_unref(bbox->box, &keywords); break; case MAIL_INDEX_SYNC_TYPE_APPEND: i_unreached();