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 */
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);
}
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)
}
}
- mail_index_keywords_free(&keywords);
+ mail_index_keywords_unref(&keywords);
}
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)
if (count == 0) {
k = i_new(struct mail_keywords, 1);
k->index = index;
+ k->refcount = 1;
return k;
}
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. */
if (count == 0) {
k = i_new(struct mail_keywords, 1);
k->index = index;
+ k->refcount = 1;
return k;
}
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++) {
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
struct mail_keywords {
struct mail_index *index;
unsigned int count;
+ int refcount;
/* variable sized list of keyword indexes */
unsigned int idx[1];
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,
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_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_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,
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);
}
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,
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)
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_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,
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;
}
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);
}
}
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_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,
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_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,
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);
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;
}
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);
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,
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);
bool skip_invalid ATTR_UNUSED)
{
*keywords_r = i_new(struct mail_keywords, 1);
+ (*keywords_r)->refcount = 1;
return 0;
}
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
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,
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;
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_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,
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)
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;
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();