dovecot-2.0: imap: Cleaned up "command pending" handling code. S...
dovecot at dovecot.org
dovecot at dovecot.org
Tue May 26 21:22:58 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/89d2dbbfa4ca
changeset: 9385:89d2dbbfa4ca
user: Timo Sirainen <tss at iki.fi>
date: Tue May 26 14:21:59 2009 -0400
description:
imap: Cleaned up "command pending" handling code. Should fix hangs caused by recent changes.
diffstat:
5 files changed, 51 insertions(+), 49 deletions(-)
src/imap/cmd-append.c | 13 ++++----
src/imap/cmd-idle.c | 7 +++-
src/imap/imap-client.c | 72 ++++++++++++++++++++++--------------------------
src/imap/imap-client.h | 2 -
src/imap/imap-search.c | 6 +++-
diffs (219 lines):
diff -r df12f1bc629f -r 89d2dbbfa4ca src/imap/cmd-append.c
--- a/src/imap/cmd-append.c Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/cmd-append.c Tue May 26 14:21:59 2009 -0400
@@ -44,7 +44,6 @@ static void client_input_append(struct c
{
struct cmd_append_context *ctx = cmd->context;
struct client *client = cmd->client;
- struct ostream *output = client->output;
bool finished;
i_assert(!client->destroyed);
@@ -80,17 +79,19 @@ static void client_input_append(struct c
return;
}
- o_stream_ref(output);
- o_stream_cork(output);
+ o_stream_cork(client->output);
finished = cmd->func(cmd);
if (!finished && cmd->state != CLIENT_COMMAND_STATE_DONE)
(void)client_handle_unfinished_cmd(cmd);
else
client_command_free(&cmd);
(void)cmd_sync_delayed(client);
- client_continue_pending_input(&client);
- o_stream_uncork(output);
- o_stream_unref(&output);
+ o_stream_uncork(client->output);
+
+ if (client->disconnected)
+ client_destroy(client, NULL);
+ else
+ client_continue_pending_input(client);
}
/* Returns -1 = error, 0 = need more data, 1 = successful. flags and
diff -r df12f1bc629f -r 89d2dbbfa4ca src/imap/cmd-idle.c
--- a/src/imap/cmd-idle.c Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/cmd-idle.c Tue May 26 14:21:59 2009 -0400
@@ -69,7 +69,7 @@ static void idle_client_input(struct cmd
case -2:
client->input_skip_line = TRUE;
idle_finish(ctx, FALSE, TRUE);
- client_continue_pending_input(&client);
+ client_continue_pending_input(client);
return;
}
@@ -85,10 +85,13 @@ static void idle_client_input(struct cmd
client->input_skip_line = FALSE;
else {
idle_finish(ctx, strcasecmp(line, "DONE") == 0, TRUE);
- client_continue_pending_input(&client);
break;
}
}
+ if (client->disconnected)
+ client_destroy(client, NULL);
+ else
+ client_continue_pending_input(client);
}
static void keepalive_timeout(struct cmd_idle_context *ctx)
diff -r df12f1bc629f -r 89d2dbbfa4ca src/imap/imap-client.c
--- a/src/imap/imap-client.c Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/imap-client.c Tue May 26 14:21:59 2009 -0400
@@ -534,19 +534,11 @@ static void client_add_missing_io(struct
}
}
-void client_continue_pending_input(struct client **_client)
-{
- struct client *client = *_client;
+void client_continue_pending_input(struct client *client)
+{
size_t size;
i_assert(!client->handling_input);
-
- if (client->disconnected) {
- if (!client->destroyed)
- client_destroy(client, NULL);
- *_client = NULL;
- return;
- }
if (client->input_lock != NULL) {
/* there's a command that has locked the input */
@@ -559,8 +551,10 @@ void client_continue_pending_input(struc
commands to finish. */
if (client_command_check_ambiguity(cmd)) {
/* we could be waiting for existing sync to finish */
- cmd_sync_delayed(client);
- return;
+ if (!cmd_sync_delayed(client))
+ return;
+ if (client_command_check_ambiguity(cmd))
+ return;
}
cmd->state = CLIENT_COMMAND_STATE_WAIT_INPUT;
}
@@ -569,8 +563,10 @@ void client_continue_pending_input(struc
/* if there's unread data in buffer, handle it. */
(void)i_stream_get_data(client->input, &size);
- if (size > 0)
- (void)client_handle_input(client);
+ if (size > 0 && !client->disconnected) {
+ if (client_handle_input(client))
+ client_continue_pending_input(client);
+ }
}
/* Skip incoming data until newline is found,
@@ -730,6 +726,8 @@ bool client_handle_input(struct client *
{
bool ret, remove_io, handled_commands = FALSE;
+ i_assert(!client->disconnected);
+
client->handling_input = TRUE;
do {
T_BEGIN {
@@ -740,23 +738,16 @@ bool client_handle_input(struct client *
} while (ret && !client->disconnected && client->io != NULL);
client->handling_input = FALSE;
- if (client->output->closed) {
- client_destroy(client, NULL);
- return TRUE;
- } else {
- if (remove_io)
- io_remove(&client->io);
- else
- client_add_missing_io(client);
- if (!handled_commands)
- return FALSE;
-
- ret = client->input_lock != NULL ? TRUE :
- cmd_sync_delayed(client);
- if (ret)
- client_continue_pending_input(&client);
- return TRUE;
- }
+ if (remove_io)
+ io_remove(&client->io);
+ else
+ client_add_missing_io(client);
+ if (!handled_commands)
+ return FALSE;
+
+ if (client->input_lock == NULL)
+ cmd_sync_delayed(client);
+ return TRUE;
}
void client_input(struct client *client)
@@ -793,6 +784,11 @@ void client_input(struct client *client)
}
o_stream_uncork(output);
o_stream_unref(&output);
+
+ if (client->disconnected)
+ client_destroy(client, NULL);
+ else
+ client_continue_pending_input(client);
}
static void client_output_cmd(struct client_command_context *cmd)
@@ -855,15 +851,13 @@ int client_output(struct client *client)
}
}
- if (client->output->closed) {
+ (void)cmd_sync_delayed(client);
+ o_stream_uncork(client->output);
+ if (client->disconnected)
client_destroy(client, NULL);
- return 1;
- } else {
- (void)cmd_sync_delayed(client);
- o_stream_uncork(client->output);
- client_continue_pending_input(&client);
- return ret;
- }
+ else
+ client_continue_pending_input(client);
+ return ret;
}
bool client_handle_search_save_ambiguity(struct client_command_context *cmd)
diff -r df12f1bc629f -r 89d2dbbfa4ca src/imap/imap-client.h
--- a/src/imap/imap-client.h Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/imap-client.h Tue May 26 14:21:59 2009 -0400
@@ -191,7 +191,7 @@ void client_command_free(struct client_c
void client_command_free(struct client_command_context **cmd);
bool client_handle_unfinished_cmd(struct client_command_context *cmd);
-void client_continue_pending_input(struct client **_client);
+void client_continue_pending_input(struct client *client);
void client_input(struct client *client);
bool client_handle_input(struct client *client);
diff -r df12f1bc629f -r 89d2dbbfa4ca src/imap/imap-search.c
--- a/src/imap/imap-search.c Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/imap-search.c Tue May 26 14:21:59 2009 -0400
@@ -439,7 +439,11 @@ static void cmd_search_more_callback(str
else
client_command_free(&cmd);
(void)cmd_sync_delayed(client);
- client_continue_pending_input(&client);
+
+ if (client->disconnected)
+ client_destroy(client, NULL);
+ else
+ client_continue_pending_input(client);
}
int cmd_search_parse_return_if_found(struct imap_search_context *ctx,
More information about the dovecot-cvs
mailing list