]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Panic if deiniting storage before closing its mailboxes.
authorTimo Sirainen <tss@iki.fi>
Wed, 7 Apr 2010 08:51:56 +0000 (11:51 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 7 Apr 2010 08:51:56 +0000 (11:51 +0300)
--HG--
branch : HEAD

src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c
src/lib-storage/mail-storage.h

index fb6f3da3ea96ccc9d2cee9ed9ca0bd0fa42abad8..4012851e65ec748557b1e6e32328cbf0f419b33c 100644 (file)
@@ -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);
index 1837a6d0cadececd423509b174e32e74d6a1b332..ad696d937f61c642f266544ef123b17a2bcd48ef 100644 (file)
@@ -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);
 }
 
index 5fc07f7015561d59b9e26661b90472dfa034b0af..589c739cc8f871637f6a4cfe035c99283582d6f9 100644 (file)
@@ -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. */