[dovecot-cvs] dovecot/src/pop3 client.c, 1.40, 1.41 client.h, 1.8,
1.9 commands.c, 1.32, 1.33
cras at dovecot.org
cras at dovecot.org
Sun Oct 10 19:25:09 EEST 2004
Update of /var/lib/cvs/dovecot/src/pop3
In directory talvi:/tmp/cvs-serv10857
Modified Files:
client.c client.h commands.c
Log Message:
Use only a single transaction for the whole duration of pop3 session. Avoids
constant locking/unlocking the indexes.
Index: client.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3/client.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- client.c 10 Oct 2004 14:32:33 -0000 1.40
+++ client.c 10 Oct 2004 16:25:06 -0000 1.41
@@ -1,6 +1,7 @@
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
+#include "buffer.h"
#include "ioloop.h"
#include "network.h"
#include "istream.h"
@@ -54,43 +55,33 @@
struct mailbox_transaction_context *t;
struct mail_search_context *ctx;
struct mail *mail;
- struct mailbox_status status;
+ buffer_t *message_sizes_buf;
int i, failed;
+ message_sizes_buf = buffer_create_dynamic(default_pool, 512);
+
memset(&search_arg, 0, sizeof(search_arg));
search_arg.type = SEARCH_ALL;
for (i = 0; i < 2; i++) {
if (sync_mailbox(client->mailbox) < 0) {
client_send_storage_error(client);
- return FALSE;
- }
- if (mailbox_get_status(client->mailbox, STATUS_MESSAGES,
- &status) < 0) {
- client_send_storage_error(client);
- return FALSE;
+ break;
}
- client->last_seen = 0;
- client->messages_count = status.messages;
- client->total_size = 0;
- client->deleted_size = 0;
-
- if (client->messages_count == 0)
- return TRUE;
-
- i_free(client->message_sizes);
- client->message_sizes = i_new(uoff_t, client->messages_count);
-
t = mailbox_transaction_begin(client->mailbox, FALSE);
ctx = mailbox_search_init(t, NULL, &search_arg, NULL,
MAIL_FETCH_VIRTUAL_SIZE, NULL);
if (ctx == NULL) {
client_send_storage_error(client);
- mailbox_transaction_rollback(t);
- return FALSE;
+ mailbox_transaction_rollback(t);
+ break;
}
+ client->last_seen = 0;
+ client->total_size = 0;
+ buffer_set_used_size(message_sizes_buf, 0);
+
failed = FALSE;
while ((mail = mailbox_search_next(ctx)) != NULL) {
uoff_t size = mail->get_virtual_size(mail);
@@ -107,18 +98,21 @@
client->last_seen = mail->seq;
client->total_size += size;
- i_assert(mail->seq <= client->messages_count);
- client->message_sizes[mail->seq-1] = size;
+ buffer_append(message_sizes_buf, &size, sizeof(size));
}
+ client->messages_count =
+ message_sizes_buf->used / sizeof(uoff_t);
if (mailbox_search_deinit(ctx) < 0) {
client_send_storage_error(client);
- mailbox_transaction_rollback(t);
- return FALSE;
+ mailbox_transaction_rollback(t);
+ break;
}
if (!failed) {
- mailbox_transaction_commit(t, 0);
+ client->trans = t;
+ client->message_sizes =
+ buffer_free_without_data(message_sizes_buf);
return TRUE;
}
@@ -126,67 +120,12 @@
mailbox_transaction_rollback(t);
}
- client_send_line(client, "-ERR [IN-USE] Couldn't sync mailbox.");
+ if (i == 2)
+ client_send_line(client, "-ERR [IN-USE] Couldn't sync mailbox.");
+ buffer_free(message_sizes_buf);
return FALSE;
}
-int client_update_mailbox(struct client *client, struct mailbox *box,
- int delete_mails)
-{
- struct mail_search_arg search_arg;
- struct mailbox_transaction_context *t;
- struct mail_search_context *ctx;
- struct mail *mail;
- struct mail_full_flags seen_flag;
- uint32_t i, bitmask;
- int failed = FALSE;
-
- if (delete_mails && client->deleted_bitmask == NULL)
- delete_mails = FALSE;
-
- memset(&search_arg, 0, sizeof(search_arg));
- search_arg.type = SEARCH_ALL;
-
- t = mailbox_transaction_begin(box, FALSE);
- ctx = mailbox_search_init(t, NULL, &search_arg, NULL, 0, NULL);
- if (ctx == NULL) {
- mailbox_transaction_rollback(t);
- return FALSE;
- }
-
- memset(&seen_flag, 0, sizeof(seen_flag));
- seen_flag.flags = MAIL_SEEN;
-
- while ((mail = mailbox_search_next(ctx)) != NULL) {
- i = mail->seq-1;
-
- bitmask = 1 << (i % CHAR_BIT);
- if (delete_mails &&
- (client->deleted_bitmask[i/CHAR_BIT] & bitmask) != 0) {
- if (mail->expunge(mail) < 0) {
- failed = TRUE;
- break;
- }
- } else if (client->seen_bitmask != NULL &&
- (client->seen_bitmask[i/CHAR_BIT] & bitmask) != 0) {
- if (mail->update_flags(mail, &seen_flag,
- MODIFY_ADD) < 0) {
- failed = TRUE;
- break;
- }
- }
- }
-
- if (mailbox_search_deinit(ctx) < 0 || failed) {
- mailbox_transaction_rollback(t);
- return FALSE;
- }
-
- mailbox_transaction_commit(t, MAILBOX_SYNC_FLAG_FULL_READ |
- MAILBOX_SYNC_FLAG_FULL_WRITE);
- return TRUE;
-}
-
struct client *client_create(int hin, int hout, struct mail_storage *storage)
{
struct client *client;
@@ -244,18 +183,14 @@
client->cmd(client);
i_assert(client->cmd == NULL);
}
- if (client->mailbox != NULL) {
- if (client->seen_bitmask != NULL) {
- (void)client_update_mailbox(client, client->mailbox,
- FALSE);
- }
+ if (client->trans != NULL)
+ mailbox_transaction_rollback(client->trans);
+ if (client->mailbox != NULL)
mailbox_close(client->mailbox);
- }
mail_storage_destroy(client->storage);
i_free(client->message_sizes);
i_free(client->deleted_bitmask);
- i_free(client->seen_bitmask);
if (client->io != NULL)
io_remove(client->io);
Index: client.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3/client.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- client.h 8 Oct 2004 20:25:00 -0000 1.8
+++ client.h 10 Oct 2004 16:25:06 -0000 1.9
@@ -17,6 +17,7 @@
struct mail_storage *storage;
struct mailbox *mailbox;
+ struct mailbox_transaction_context *trans;
time_t last_input, last_output;
unsigned int bad_counter;
@@ -29,7 +30,6 @@
uint32_t last_seen;
unsigned char *deleted_bitmask;
- unsigned char *seen_bitmask;
unsigned int deleted:1;
unsigned int waiting_input:1;
@@ -43,9 +43,6 @@
/* Disconnect client connection */
void client_disconnect(struct client *client);
-int client_update_mailbox(struct client *client, struct mailbox *box,
- int delete_mails);
-
/* Send a line of data to client */
int client_send_line(struct client *client, const char *fmt, ...)
__attr_format__(2, 3);
Index: commands.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3/commands.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- commands.c 10 Oct 2004 14:32:33 -0000 1.32
+++ commands.c 10 Oct 2004 16:25:06 -0000 1.33
@@ -178,20 +178,46 @@
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.");
else
@@ -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;
More information about the dovecot-cvs
mailing list