struct mail_storage_service_user {
pool_t pool;
+ int refcount;
+
struct mail_storage_service_ctx *service_ctx;
struct mail_storage_service_input input;
enum mail_storage_service_flags flags;
mail_user = mail_user_alloc_nodup_set(user->input.username,
user->user_info, user->user_set);
mail_user->_service_user = user;
+ mail_storage_service_user_ref(user);
mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
mail_user_set_vars(mail_user, ctx->service->name,
&user->input.local_ip, &user->input.remote_ip);
}
user = p_new(user_pool, struct mail_storage_service_user, 1);
+ user->refcount = 1;
user->service_ctx = ctx;
user->pool = user_pool;
user->input = *input;
ret = mail_storage_service_next(ctx, user, mail_user_r, error_r);
if (ret < 0) {
- mail_storage_service_user_free(&user);
+ mail_storage_service_user_unref(&user);
return ret;
}
*user_r = user;
return 1;
}
-void mail_storage_service_user_free(struct mail_storage_service_user **_user)
+void mail_storage_service_user_ref(struct mail_storage_service_user *user)
+{
+ i_assert(user->refcount > 0);
+ user->refcount++;
+}
+
+void mail_storage_service_user_unref(struct mail_storage_service_user **_user)
{
struct mail_storage_service_user *user = *_user;
*_user = NULL;
+ i_assert(user->refcount > 0);
+ if (--user->refcount > 0)
+ return;
+
if (user->ioloop_ctx != NULL) {
if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0) {
io_loop_context_remove_callbacks(user->ioloop_ctx,
struct mail_storage_service_user **user_r,
struct mail_user **mail_user_r,
const char **error_r);
-void mail_storage_service_user_free(struct mail_storage_service_user **user);
+void mail_storage_service_user_ref(struct mail_storage_service_user *user);
+void mail_storage_service_user_unref(struct mail_storage_service_user **user);
+/* FIXME: for backwards compatibility - remove */
+#define mail_storage_service_user_free(user) \
+ mail_storage_service_user_unref(user)
/* Initialize iterating through all users. */
void mail_storage_service_all_init(struct mail_storage_service_ctx *ctx);
/* Initialize iterating through all users with a user mask hint to the
dict_deinit(&user->_attr_dict);
}
mail_namespaces_deinit(&user->namespaces);
+ if (user->_service_user != NULL)
+ mail_storage_service_user_unref(&user->_service_user);
}
static void mail_user_stats_fill_base(struct mail_user *user ATTR_UNUSED,
user2 = mail_user_alloc(user->username, user->set_info,
user->unexpanded_set);
- user2->_service_user = user->_service_user;
+ if (user2->_service_user != NULL) {
+ user2->_service_user = user->_service_user;
+ mail_storage_service_user_ref(user2->_service_user);
+ }
if (user->_home != NULL)
mail_user_set_home(user2, user->_home);
mail_user_set_vars(user2, user->service,