struct istream *input;
struct ostream *output;
+ unsigned int skip_lines;
unsigned int connect_counter;
unsigned int transaction_id_counter;
while ((ret = i_stream_read(dict->input)) > 0) {
line = i_stream_next_line(dict->input);
- if (line != NULL)
- return line;
+ if (line != NULL) {
+ if (dict->skip_lines == 0)
+ return line;
+ /* ignore this reply and wait for the next line */
+ dict->skip_lines--;
+ }
}
i_assert(ret < 0);
return &ctx->ctx;
}
-static int client_dict_transaction_commit(struct dict_transaction_context *_ctx)
+static int client_dict_transaction_commit(struct dict_transaction_context *_ctx,
+ bool async)
{
struct client_dict_transaction_context *ctx =
(struct client_dict_transaction_context *)_ctx;
DICT_PROTOCOL_CMD_ROLLBACK, ctx->id);
if (client_dict_send_transaction_query(ctx, query) < 0)
ret = -1;
- else if (ret == 0) {
+ else if (ret < 0) {
+ /* rollback sent, it has no reply */
+ } else if (async) {
+ /* don't wait for the reply. if we read it later,
+ ignore it. */
+ dict->skip_lines++;
+ } else {
/* read reply */
line = client_dict_read_line(dict);
if (line == NULL || *line != DICT_PROTOCOL_REPLY_OK)
return &ctx->ctx;
}
-static int db_dict_transaction_commit(struct dict_transaction_context *_ctx)
+static int db_dict_transaction_commit(struct dict_transaction_context *_ctx,
+ bool async ATTR_UNUSED)
{
struct db_dict_transaction_context *ctx =
(struct db_dict_transaction_context *)_ctx;
void (*iterate_deinit)(struct dict_iterate_context *ctx);
struct dict_transaction_context *(*transaction_init)(struct dict *dict);
- int (*transaction_commit)(struct dict_transaction_context *ctx);
+ int (*transaction_commit)(struct dict_transaction_context *ctx,
+ bool async);
void (*transaction_rollback)(struct dict_transaction_context *ctx);
void (*set)(struct dict_transaction_context *ctx,
return &ctx->ctx;
}
-static int sql_dict_transaction_commit(struct dict_transaction_context *_ctx)
+static int sql_dict_transaction_commit(struct dict_transaction_context *_ctx,
+ bool async ATTR_UNUSED)
{
struct sql_dict_transaction_context *ctx =
(struct sql_dict_transaction_context *)_ctx;
struct dict_transaction_context *ctx = *_ctx;
*_ctx = NULL;
- return ctx->dict->v.transaction_commit(ctx);
+ return ctx->dict->v.transaction_commit(ctx, FALSE);
+}
+
+void dict_transaction_commit_async(struct dict_transaction_context **_ctx)
+{
+ struct dict_transaction_context *ctx = *_ctx;
+
+ *_ctx = NULL;
+ ctx->dict->v.transaction_commit(ctx, TRUE);
}
void dict_transaction_rollback(struct dict_transaction_context **_ctx)
struct dict_transaction_context *dict_transaction_begin(struct dict *dict);
/* Commit the transaction. Returns 0 if ok, -1 if failed. */
int dict_transaction_commit(struct dict_transaction_context **ctx);
+/* Commit the transaction, but don't wait to see if it finishes successfully. */
+void dict_transaction_commit_async(struct dict_transaction_context **ctx);
/* Rollback all changes made in transaction. */
void dict_transaction_rollback(struct dict_transaction_context **ctx);