char *error;
const char **paths;
enum dict_iterate_flags flags;
+ int refcount;
pool_t results_pool;
ARRAY(struct client_dict_iter_result) results;
i_unreached();
}
-static void client_dict_iterate_free(struct client_dict_iterate_context *ctx)
+static void client_dict_iterate_unref(struct client_dict_iterate_context *ctx)
{
- if (!ctx->deinit || !ctx->finished)
+ i_assert(ctx->refcount > 0);
+ if (--ctx->refcount > 0)
return;
i_free(ctx->error);
i_free(ctx);
} else switch (reply) {
case DICT_PROTOCOL_REPLY_ITER_FINISHED:
/* end of iteration */
+ i_assert(!ctx->finished);
ctx->finished = TRUE;
client_dict_iter_api_callback(ctx, cmd, extra_args);
- client_dict_iterate_free(ctx);
+ client_dict_iterate_unref(ctx);
return;
case DICT_PROTOCOL_REPLY_OK:
/* key \t value */
if (error != NULL) {
if (ctx->error == NULL)
ctx->error = i_strdup(error);
+ i_assert(!ctx->finished);
ctx->finished = TRUE;
client_dict_iter_api_callback(ctx, cmd, extra_args);
- client_dict_iterate_free(ctx);
+ client_dict_iterate_unref(ctx);
return;
}
cmd->unfinished = TRUE;
ctx->results_pool = pool_alloconly_create("client dict iteration", 512);
ctx->flags = flags;
ctx->paths = p_strarray_dup(system_pool, paths);
+ ctx->refcount = 1;
i_array_init(&ctx->results, 64);
return &ctx->ctx;
}
cmd->callback = client_dict_iter_async_callback;
cmd->retry_errors = TRUE;
+ ctx->refcount++;
client_dict_cmd_send(dict, &cmd, NULL);
}
(struct client_dict_iterate_context *)_ctx;
int ret = ctx->error != NULL ? -1 : 0;
+ i_assert(!ctx->deinit);
ctx->deinit = TRUE;
*error_r = t_strdup(ctx->error);
array_free(&ctx->results);
pool_unref(&ctx->results_pool);
i_free(ctx->paths);
- client_dict_iterate_free(ctx);
+ client_dict_iterate_unref(ctx);
client_dict_add_timeout(dict);
return ret;