From: Timo Sirainen Date: Wed, 7 Apr 2010 08:51:56 +0000 (+0300) Subject: lib-storage: Panic if deiniting storage before closing its mailboxes. X-Git-Tag: 2.0.beta5~168 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=420040a5930a2b497e79ff0b5f59ba4b764a5b39;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Panic if deiniting storage before closing its mailboxes. --HG-- branch : HEAD --- diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index fb6f3da3ea..4012851e65 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -66,7 +66,12 @@ struct mail_storage { /* private: */ pool_t pool; struct mail_storage *prev, *next; + /* counting number of times mail_storage_create() has returned this + same storage. */ int refcount; + /* counting number of objects (e.g. mailbox) that have a pointer + to this storage. */ + int obj_refcount; const char *unique_root_dir; char *error_string; @@ -445,6 +450,9 @@ extern struct mail_module_register mail_module_register; extern MODULE_CONTEXT_DEFINE(mail_storage_mail_index_module, &mail_index_module_register); +void mail_storage_obj_ref(struct mail_storage *storage); +void mail_storage_obj_unref(struct mail_storage *storage); + /* Set error message in storage. Critical errors are logged with i_error(), but user sees only "internal error" message. */ void mail_storage_clear_error(struct mail_storage *storage); diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 1837a6d0ca..ad696d937f 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -327,11 +327,6 @@ int mail_storage_create(struct mail_namespace *ns, const char *driver, return 0; } -void mail_storage_ref(struct mail_storage *storage) -{ - storage->refcount++; -} - void mail_storage_unref(struct mail_storage **_storage) { struct mail_storage *storage = *_storage; @@ -345,6 +340,9 @@ void mail_storage_unref(struct mail_storage **_storage) return; } + if (storage->obj_refcount != 0) + i_panic("Trying to deinit storage before freeing its objects"); + DLLIST_REMOVE(&storage->user->storages, storage); if (storage->v.destroy != NULL) @@ -357,6 +355,21 @@ void mail_storage_unref(struct mail_storage **_storage) mail_index_alloc_cache_destroy_unrefed(); } +void mail_storage_obj_ref(struct mail_storage *storage) +{ + i_assert(storage->refcount > 0); + + storage->obj_refcount++; +} + +void mail_storage_obj_unref(struct mail_storage *storage) +{ + i_assert(storage->refcount > 0); + i_assert(storage->obj_refcount > 0); + + storage->obj_refcount--; +} + void mail_storage_clear_error(struct mail_storage *storage) { i_free_and_null(storage->error_string); @@ -514,6 +527,8 @@ struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *name, box = storage->v.mailbox_alloc(storage, new_list, name, flags); hook_mailbox_allocated(box); } T_END; + + mail_storage_obj_ref(box->storage); return box; } @@ -614,6 +629,7 @@ void mailbox_free(struct mailbox **_box) mailbox_close(box); box->v.free(box); + mail_storage_obj_unref(box->storage); pool_unref(&box->pool); } diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index 5fc07f7015..589c739cc8 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -295,7 +295,6 @@ struct mail_storage *mail_storage_find_class(const char *name); exists. The storage is put into ns->storage. */ int mail_storage_create(struct mail_namespace *ns, const char *driver, enum mail_storage_flags flags, const char **error_r); -void mail_storage_ref(struct mail_storage *storage); void mail_storage_unref(struct mail_storage **storage); /* Returns the mail storage settings. */