]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added reference counting to struct mail_keywords and related APIs.
authorTimo Sirainen <tss@iki.fi>
Mon, 22 Jun 2009 21:45:56 +0000 (17:45 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 22 Jun 2009 21:45:56 +0000 (17:45 -0400)
--HG--
branch : HEAD

26 files changed:
src/imap/cmd-append.c
src/imap/cmd-copy.c
src/imap/cmd-store.c
src/lib-index/mail-index-sync.c
src/lib-index/mail-index-transaction.c
src/lib-index/mail-index.h
src/lib-lda/mail-deliver.c
src/lib-storage/index/cydir/cydir-storage.c
src/lib-storage/index/dbox/dbox-storage.c
src/lib-storage/index/dbox/dbox-sync-rebuild.c
src/lib-storage/index/index-storage.c
src/lib-storage/index/index-storage.h
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/maildir/maildir-sync-index.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/index/mbox/mbox-sync.c
src/lib-storage/index/raw/raw-storage.c
src/lib-storage/mail-search.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c
src/lib-storage/mail-storage.h
src/lib-storage/test-mailbox.c
src/plugins/convert/convert-storage.c
src/plugins/lazy-expunge/lazy-expunge-plugin.c
src/plugins/virtual/virtual-storage.c
src/plugins/virtual/virtual-sync.c

index a76aae9271e365a4c65c3d12a260cf38a6a6baff..cec4ee9e1b24708953feb32b694f5521513a4b0b 100644 (file)
@@ -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 */
index 7969de2a240fa59c3362bc4c6bbc20b8692f6ddb..d9fed3830226379113338a2c145e398b1a19eec3 100644 (file)
@@ -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);
        }
index c021f86b1fd5ef9fa4fd7470599c249bc349350e..20a5caa3b7fb96198ab03e488f3ff8f52acb2895 100644 (file)
@@ -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)
index b5b746c104dbcb788a7e0007900b75f1f561dcad..d6378705f2313ffb9f5398fb6bee07d3e8bbc4fe 100644 (file)
@@ -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)
index eafc3093cc5f74bbf11439e625a0369be5325915..6a28d48408794cccf68fbec09909cefef7bbe82f 100644 (file)
@@ -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
index 03f80739a503266ba35ebc78c5d07b1676d62b69..7d775d4e22b8669c86ec5c1d80bbeb5578f00b05 100644 (file)
@@ -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,
index d5233aef292416c9ed56889894c8becd3efde5ad..5328b36fcbbad5d304c3e90c2ddca754e7bb651d 100644 (file)
@@ -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);
index 02b22cf0cc8a86569fe0c0e70e0782ce7d97dbd3..872598e74a0b4e2fe1e57922a0101eecdf4963c5 100644 (file)
@@ -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,
index ef05b3329fef6ac14f204186229accc05bff25e7..11888241f421e1372a9e81df486524e50133a4f4 100644 (file)
@@ -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,
index a6d1e05eb24df277576437b2a74d6cbe33cb9b6c..6c0c54b9aa2cf182e2e8e81ea8ca1e1a73ad1805 100644 (file)
@@ -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,
index 6564b96705725efaa25ec03eda617050e60b7d56..062ad63f8963fe7d85db160309b897c1ca7b694a 100644 (file)
@@ -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)
index 1d4c0660d9ac069a6d7c6c17e86c0b216149b2b7..d6c845e8eb42b423e1dc46f79527cd1758c30e90 100644 (file)
@@ -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);
 
index 2da129f39d50707072a903f352779dd6d6c0a29a..c4ecb46012604b11aa927b4be2729b0d6258cd8b 100644 (file)
@@ -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,
index 97e090ebfc881c18f8e607ac7815c39c5f6a1339..e4cc230e4bf9f234fd589291cd729a98f26c0680 100644 (file)
@@ -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;
                }
index 00f3c59e8bafafdefd918d416cc2cb55e8a1c33a..58464c30059abf159c9bcac35edb978662efbd0f 100644 (file)
@@ -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,
index 70bf80588f653a1aaddb19660c9537043edd01ce..6e268955bc6feaf25e056ef4c27bf8b284472ae2 100644 (file)
@@ -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
index 22374432faa41b77c102dbc0b12c76186524bb80..db04876a7723da49a2bfb22f928963ec099a222d 100644 (file)
@@ -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,
index 9b997170bbd33e471bc324fbb96584c7c0af2b5b..7c5b1f159fab55ec1ffd106f3eea429ece594409 100644 (file)
@@ -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;
 }
 
index 4ff4953bd02e8f114b275a73c1fbcfc8acc49b58..d3ac3ea3f3d67b1daefb0259e0f1b79485d754f3 100644 (file)
@@ -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);
 
index 5c1588b41e9e5995c2788e974fdfc759d4cfd06f..48fa1c4f33c8c31f3c2827f5bbbe48bbd3c7a234 100644 (file)
@@ -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,
index 14c92961f0851d66a60c8ea29dd79542d8063a08..99fb0adec21fc199ea0dc114179f5cc6550c0092 100644 (file)
@@ -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);
index 243654c63f38686581bcdcb4aa360841fd1d2008..0d3614f2efb086c840945063b432d9498904fe48 100644 (file)
@@ -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,
index ece802a3fb52a15832a3a41fc48229bd8c38c4a8..9c337475ca379a93170d4a58781f6a881b845517 100644 (file)
@@ -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;
index 84623b4378c7b2819f45cd3f6eaf0d15e4d4446c..a823ee3bc8c59ef9543fc06e832baf572cbfb6a1 100644 (file)
@@ -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);
 }
index 4bb8fbe4f5a24083f042b32d181322a70aaf8ca4..12893d828e4f74c0802a0fbb2127e743a581347f 100644 (file)
@@ -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,
index 538a49e78d89f505ccb39bf32e08c586a58a5ce8..e34fd5ef40182d5e1a32165153e6a8ce9944a9cb 100644 (file)
@@ -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();