Mercurial > dovecot > original-hg > dovecot-1.2
diff src/pop3/commands.c @ 2722:8c5bcd6585a4 HEAD
Use only a single transaction for the whole duration of pop3 session. Avoids
constant locking/unlocking the indexes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 10 Oct 2004 19:25:06 +0300 |
parents | f8adc5cb2508 |
children | 3470bb04fb57 |
line wrap: on
line diff
--- a/src/pop3/commands.c Sun Oct 10 18:56:00 2004 +0300 +++ b/src/pop3/commands.c Sun Oct 10 19:25:06 2004 +0300 @@ -178,19 +178,45 @@ return TRUE; } +static int expunge_mails(struct client *client) +{ + struct mail_search_arg search_arg; + struct mail_search_context *ctx; + struct mail *mail; + uint32_t idx; + + if (client->deleted_bitmask == NULL) + return TRUE; + + memset(&search_arg, 0, sizeof(search_arg)); + search_arg.type = SEARCH_ALL; + + ctx = mailbox_search_init(client->trans, NULL, &search_arg, + NULL, 0, NULL); + while ((mail = mailbox_search_next(ctx)) != NULL) { + idx = mail->seq - 1; + if ((client->deleted_bitmask[idx / CHAR_BIT] & + 1 << (idx % CHAR_BIT)) != 0) { + if (mail->expunge(mail) < 0) + return FALSE; + } + } + + return mailbox_search_deinit(ctx) == 0; +} + static int cmd_quit(struct client *client, const char *args __attr_unused__) { if (client->deleted) { - if (!client_update_mailbox(client, client->mailbox, TRUE)) { + if (!expunge_mails(client)) { client_send_storage_error(client); client_disconnect(client); return TRUE; } + } - /* don't sync them again at client_destroy() */ - i_free(client->seen_bitmask); - client->seen_bitmask = NULL; - } + mailbox_transaction_commit(client->trans, MAILBOX_SYNC_FLAG_FULL_WRITE); + client->trans = NULL; if (!client->deleted) client_send_line(client, "+OK Logging out."); @@ -202,7 +228,6 @@ } struct fetch_context { - struct mailbox_transaction_context *t; struct mail_search_context *search_ctx; struct istream *stream; uoff_t body_lines; @@ -217,7 +242,6 @@ static void fetch_deinit(struct fetch_context *ctx) { (void)mailbox_search_deinit(ctx->search_ctx); - (void)mailbox_transaction_commit(ctx->t, 0); i_free(ctx); } @@ -320,8 +344,8 @@ ctx->search_arg.type = SEARCH_SEQSET; ctx->search_arg.value.seqset = &ctx->seqset; - ctx->t = mailbox_transaction_begin(client->mailbox, FALSE); - ctx->search_ctx = mailbox_search_init(ctx->t, NULL, &ctx->search_arg, + ctx->search_ctx = mailbox_search_init(client->trans, NULL, + &ctx->search_arg, NULL, MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY, NULL); mail = mailbox_search_next(ctx->search_ctx); @@ -334,12 +358,11 @@ if (body_lines == (uoff_t)-1 && !no_flag_updates) { /* mark the message seen with RETR command */ - if (client->seen_bitmask == NULL) { - client->seen_bitmask = - i_malloc(MSGS_BITMASK_SIZE(client)); - } - client->seen_bitmask[msgnum / CHAR_BIT] |= - 1 << (msgnum % CHAR_BIT); + struct mail_full_flags seen_flag; + memset(&seen_flag, 0, sizeof(seen_flag)); + seen_flag.flags = MAIL_SEEN; + + (void)mail->update_flags(mail, &seen_flag, MODIFY_ADD); } ctx->body_lines = body_lines; @@ -372,7 +395,6 @@ static int cmd_rset(struct client *client, const char *args __attr_unused__) { - struct mailbox_transaction_context *t; struct mail_search_context *search_ctx; struct mail *mail; struct mail_search_arg search_arg; @@ -387,6 +409,10 @@ client->deleted_size = 0; } + /* forget all our seen flag updates as well.. */ + mailbox_transaction_rollback(client->trans); + client->trans = mailbox_transaction_begin(client->mailbox, FALSE); + if (enable_last_command) { /* remove all \Seen flags */ memset(&search_arg, 0, sizeof(search_arg)); @@ -395,16 +421,14 @@ memset(&seen_flag, 0, sizeof(seen_flag)); seen_flag.flags = MAIL_SEEN; - t = mailbox_transaction_begin(client->mailbox, FALSE); - search_ctx = mailbox_search_init(t, NULL, &search_arg, - NULL, 0, NULL); + search_ctx = mailbox_search_init(client->trans, NULL, + &search_arg, NULL, 0, NULL); while ((mail = mailbox_search_next(search_ctx)) != NULL) { if (mail->update_flags(mail, &seen_flag, MODIFY_REMOVE) < 0) break; } (void)mailbox_search_deinit(search_ctx); - (void)mailbox_transaction_commit(t, 0); } client_send_line(client, "+OK"); @@ -435,7 +459,6 @@ } struct cmd_uidl_context { - struct mailbox_transaction_context *t; struct mail_search_context *search_ctx; unsigned int message; @@ -474,7 +497,6 @@ /* finished */ (void)mailbox_search_deinit(ctx->search_ctx); - (void)mailbox_transaction_commit(ctx->t, 0); client->cmd = NULL; @@ -507,9 +529,8 @@ ctx->search_arg.value.seqset = &ctx->seqset; } - ctx->t = mailbox_transaction_begin(client->mailbox, FALSE); - ctx->search_ctx = mailbox_search_init(ctx->t, NULL, &ctx->search_arg, - NULL, 0, NULL); + ctx->search_ctx = mailbox_search_init(client->trans, NULL, + &ctx->search_arg, NULL, 0, NULL); if (message == 0) { client->cmd = cmd_uidl_callback; client->cmd_context = ctx;