}
req->listed = FALSE;
- if (client->requests_count == 0 && client->ioloop != NULL)
+ if (client->requests_count == 0 && client->waiting)
io_loop_stop(client->ioloop);
}
http_client_request_remove(req);
- if (client->requests_count == 0 && client->ioloop != NULL)
+ if (client->requests_count == 0 && client->waiting)
io_loop_stop(client->ioloop);
if (req->delayed_error != NULL)
http_client_request_continue_payload(struct http_client_request **_req,
const unsigned char *data, size_t size)
{
- struct ioloop *prev_ioloop = current_ioloop;
+ struct ioloop *prev_ioloop, *client_ioloop, *prev_client_ioloop;
struct http_client_request *req = *_req;
struct http_client_connection *conn = req->conn;
struct http_client *client = req->client;
} else {
/* Wait for payload data to be written */
- i_assert(client->ioloop == NULL);
- client->ioloop = io_loop_create();
- http_client_switch_ioloop(client);
+ prev_ioloop = current_ioloop;
+ client_ioloop = io_loop_create();
+ prev_client_ioloop = http_client_switch_ioloop(client);
if (client->set.dns_client != NULL)
dns_client_switch_ioloop(client->set.dns_client);
+ client->waiting = TRUE;
while (req->state < HTTP_REQUEST_STATE_PAYLOAD_IN) {
e_debug(req->event, "Waiting for request to finish");
if (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT)
o_stream_set_flush_pending(req->payload_output, TRUE);
- io_loop_run(client->ioloop);
+
+ io_loop_run(client_ioloop);
if (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT &&
req->payload_input->eof) {
req->payload_input = NULL;
break;
}
- }
+ }
+ client->waiting = FALSE;
- io_loop_set_current(prev_ioloop);
- http_client_switch_ioloop(client);
+ if (prev_client_ioloop != NULL)
+ io_loop_set_current(prev_client_ioloop);
+ else
+ io_loop_set_current(prev_ioloop);
+ (void)http_client_switch_ioloop(client);
if (client->set.dns_client != NULL)
dns_client_switch_ioloop(client->set.dns_client);
- io_loop_set_current(client->ioloop);
- io_loop_destroy(&client->ioloop);
+ io_loop_set_current(client_ioloop);
+ io_loop_destroy(&client_ioloop);
}
switch (req->state) {
i_assert(!pipelined);
conn->output_locked = TRUE;
http_client_connection_stop_request_timeout(conn);
- if (req->client->ioloop != NULL)
+ if (req->client->waiting)
io_loop_stop(req->client->ioloop);
} else {
/* finished sending payload */
i_stream_unref(&req->payload_input);
}
}
- if (req->payload_wait && req->client->ioloop != NULL)
+ if (req->payload_wait)
io_loop_stop(req->client->ioloop);
return TRUE;
}
if (req->queue != NULL)
http_client_queue_drop_request(req->queue, req);
- if (req->payload_wait && req->client->ioloop != NULL)
+ if (req->payload_wait) {
+ i_assert(req->client->ioloop != NULL);
io_loop_stop(req->client->ioloop);
+ }
http_client_request_destroy(&req);
}
if (req->queue != NULL)
http_client_queue_drop_request(req->queue, req);
- if (req->payload_wait && req->client->ioloop != NULL)
+ if (req->payload_wait) {
+ i_assert(req->client->ioloop != NULL);
io_loop_stop(req->client->ioloop);
+ }
http_client_request_unref(&req);
}
pool_unref(&client->pool);
}
-void http_client_switch_ioloop(struct http_client *client)
+struct ioloop *http_client_switch_ioloop(struct http_client *client)
{
+ struct ioloop *prev_ioloop = client->ioloop;
struct http_client_peer *peer;
struct http_client_host *host;
}
http_client_context_switch_ioloop(client->cctx);
+
+ client->ioloop = current_ioloop;
+ return prev_ioloop;
}
void http_client_wait(struct http_client *client)
{
- struct ioloop *prev_ioloop = current_ioloop;
+ struct ioloop *prev_ioloop, *client_ioloop, *prev_client_ioloop;
i_assert(client->ioloop == NULL);
if (client->requests_count == 0)
return;
- client->ioloop = io_loop_create();
- http_client_switch_ioloop(client);
+ prev_ioloop = current_ioloop;
+ client_ioloop = io_loop_create();
+ prev_client_ioloop = http_client_switch_ioloop(client);
if (client->set.dns_client != NULL)
dns_client_switch_ioloop(client->set.dns_client);
/* either we're waiting for network I/O or we're getting out of a
callback using timeout_add_short(0) */
- i_assert(io_loop_have_ios(client->ioloop) ||
- io_loop_have_immediate_timeouts(client->ioloop));
+ i_assert(io_loop_have_ios(client_ioloop) ||
+ io_loop_have_immediate_timeouts(client_ioloop));
+ client->waiting = TRUE;
do {
e_debug(client->event,
"Waiting for %d requests to finish", client->requests_count);
- io_loop_run(client->ioloop);
+ io_loop_run(client_ioloop);
} while (client->requests_count > 0);
+ client->waiting = FALSE;
e_debug(client->event, "All requests finished");
- io_loop_set_current(prev_ioloop);
- http_client_switch_ioloop(client);
+ if (prev_client_ioloop != NULL)
+ io_loop_set_current(prev_client_ioloop);
+ else
+ io_loop_set_current(prev_ioloop);
+ (void)http_client_switch_ioloop(client);
if (client->set.dns_client != NULL)
dns_client_switch_ioloop(client->set.dns_client);
- io_loop_set_current(client->ioloop);
- io_loop_destroy(&client->ioloop);
+ io_loop_set_current(client_ioloop);
+ io_loop_destroy(&client_ioloop);
}
unsigned int http_client_get_pending_request_count(struct http_client *client)