Mercurial > dovecot > core-2.2
changeset 5405:22d04968449a HEAD
Don't crash if another search is started while we're still building the
index for the first search.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 25 Mar 2007 20:00:04 +0300 |
parents | fd57e9c99846 |
children | 82d6f9673c05 |
files | src/plugins/fts/fts-api-private.h src/plugins/fts/fts-api.c src/plugins/fts/fts-api.h src/plugins/fts/fts-storage.c |
diffstat | 4 files changed, 48 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/plugins/fts/fts-api-private.h Sun Mar 25 19:33:16 2007 +0300 +++ b/src/plugins/fts/fts-api-private.h Sun Mar 25 20:00:04 2007 +0300 @@ -45,6 +45,8 @@ enum fts_backend_flags flags; struct fts_backend_vfuncs v; + + unsigned int building:1; }; struct fts_backend_build_context {
--- a/src/plugins/fts/fts-api.c Sun Mar 25 19:33:16 2007 +0300 +++ b/src/plugins/fts/fts-api.c Sun Mar 25 20:00:04 2007 +0300 @@ -63,6 +63,10 @@ struct fts_backend_build_context * fts_backend_build_init(struct fts_backend *backend, uint32_t *last_uid_r) { + i_assert(!backend->building); + + backend->building = TRUE; + return backend->v.build_init(backend, last_uid_r); } @@ -74,9 +78,15 @@ int fts_backend_build_deinit(struct fts_backend_build_context *ctx) { + ctx->backend->building = FALSE; return ctx->backend->v.build_deinit(ctx); } +bool fts_backend_is_building(struct fts_backend *backend) +{ + return backend->building; +} + void fts_backend_expunge(struct fts_backend *backend, struct mail *mail) { backend->v.expunge(backend, mail);
--- a/src/plugins/fts/fts-api.h Sun Mar 25 19:33:16 2007 +0300 +++ b/src/plugins/fts/fts-api.h Sun Mar 25 20:00:04 2007 +0300 @@ -32,6 +32,9 @@ /* Finish adding new data to the index. */ int fts_backend_build_deinit(struct fts_backend_build_context *ctx); +/* Returns TRUE if there exists a build context. */ +bool fts_backend_is_building(struct fts_backend *backend); + /* Expunge given mail from the backend. Note that the transaction may still fail later. */ void fts_backend_expunge(struct fts_backend *backend, struct mail *mail);
--- a/src/plugins/fts/fts-storage.c Sun Mar 25 19:33:16 2007 +0300 +++ b/src/plugins/fts/fts-storage.c Sun Mar 25 20:00:04 2007 +0300 @@ -37,7 +37,9 @@ struct mail_search_arg *args, *best_arg; struct fts_backend *backend; struct fts_storage_build_context *build_ctx; + struct mailbox_transaction_context *t; + unsigned int build_initialized:1; unsigned int locked:1; }; @@ -222,9 +224,9 @@ return ret; } -static int fts_build_init(struct fts_search_context *fctx, - struct mailbox_transaction_context *t) +static int fts_build_init(struct fts_search_context *fctx) { + struct mailbox_transaction_context *t = fctx->t; struct fts_backend *backend = fctx->backend; struct fts_storage_build_context *ctx; struct fts_backend_build_context *build; @@ -528,6 +530,26 @@ } } +static bool fts_try_build_init(struct fts_search_context *fctx) +{ + if (fctx->backend == NULL) { + fctx->build_initialized = TRUE; + return TRUE; + } + + if (fts_backend_is_building(fctx->backend)) + return FALSE; + fctx->build_initialized = TRUE; + + if (fts_build_init(fctx) < 0) + fctx->backend = NULL; + else if (fctx->build_ctx == NULL) { + /* the index was up to date */ + fts_search_init(fctx->t->box, fctx); + } + return TRUE; +} + static struct mail_search_context * fts_mailbox_search_init(struct mailbox_transaction_context *t, const char *charset, struct mail_search_arg *args, @@ -542,6 +564,7 @@ ctx = fbox->super.search_init(t, charset, args, sort_program); fctx = i_new(struct fts_search_context, 1); + fctx->t = t; fctx->args = args; array_idx_set(&ctx->module_contexts, fts_storage_module_id, &fctx); @@ -562,15 +585,7 @@ best_exact_arg : best_fast_arg; } - if (fctx->backend != NULL) { - if (fts_build_init(fctx, t) < 0) - fctx->backend = NULL; - else if (fctx->build_ctx == NULL) { - /* the index was up to date */ - fts_search_init(t->box, fctx); - } - } - + fts_try_build_init(fctx); return ctx; } @@ -581,6 +596,13 @@ struct fts_search_context *fctx = FTS_CONTEXT(ctx); int ret; + if (!fctx->build_initialized) { + if (!fts_try_build_init(fctx)) { + *tryagain_r = TRUE; + return 0; + } + } + if (fctx->build_ctx != NULL) { /* still building the index */ ret = fts_build_more(fctx->build_ctx);