{
struct cmd_append_context *ctx = cmd->context;
struct client *client = cmd->client;
- struct ostream *output = client->output;
bool finished;
i_assert(!client->destroyed);
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
case -2:
client->input_skip_line = TRUE;
idle_finish(ctx, FALSE, TRUE);
- client_continue_pending_input(&client);
+ client_continue_pending_input(client);
return;
}
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)
}
}
-void client_continue_pending_input(struct client **_client)
+void client_continue_pending_input(struct client *client)
{
- struct client *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 */
struct client_command_context *cmd = client->input_lock;
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;
}
/* 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,
{
bool ret, remove_io, handled_commands = FALSE;
+ i_assert(!client->disconnected);
+
client->handling_input = TRUE;
do {
T_BEGIN {
} 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;
+ 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 (client->input_lock == NULL)
+ cmd_sync_delayed(client);
+ return TRUE;
}
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)
}
}
- 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)