conn = i_new(struct http_server_connection, 1);
conn->refcount = 1;
conn->server = server;
+ conn->ioloop = current_ioloop;
conn->ssl = ssl;
conn->callbacks = callbacks;
conn->context = context;
callback(context, &tunnel);
}
-void http_server_connection_switch_ioloop(struct http_server_connection *conn)
+struct ioloop *
+http_server_connection_switch_ioloop_to(struct http_server_connection *conn,
+ struct ioloop *ioloop)
{
- if (conn->switching_ioloop)
- return;
+ struct ioloop *prev_ioloop = conn->ioloop;
- conn->switching_ioloop = TRUE;
- if (conn->to_input != NULL)
- conn->to_input = io_loop_move_timeout(&conn->to_input);
- if (conn->to_idle != NULL)
- conn->to_idle = io_loop_move_timeout(&conn->to_idle);
- if (conn->io_resp_payload != NULL)
- conn->io_resp_payload = io_loop_move_io(&conn->io_resp_payload);
- if (conn->payload_handler != NULL)
- http_server_payload_handler_switch_ioloop(conn->payload_handler);
+ if (conn->ioloop_switching != NULL)
+ return conn->ioloop_switching;
+
+ conn->ioloop = ioloop;
+ conn->ioloop_switching = prev_ioloop;
+ connection_switch_ioloop_to(&conn->conn, ioloop);
+ if (conn->to_input != NULL) {
+ conn->to_input =
+ io_loop_move_timeout_to(ioloop, &conn->to_input);
+ }
+ if (conn->to_idle != NULL) {
+ conn->to_idle =
+ io_loop_move_timeout_to(ioloop, &conn->to_idle);
+ }
+ if (conn->io_resp_payload != NULL) {
+ conn->io_resp_payload =
+ io_loop_move_io_to(ioloop, &conn->io_resp_payload);
+ }
+ if (conn->payload_handler != NULL) {
+ http_server_payload_handler_switch_ioloop(
+ conn->payload_handler, ioloop);
+ }
if (conn->incoming_payload != NULL)
- i_stream_switch_ioloop(conn->incoming_payload);
- connection_switch_ioloop(&conn->conn);
- conn->switching_ioloop = FALSE;
+ i_stream_switch_ioloop_to(conn->incoming_payload, ioloop);
+ conn->ioloop_switching = NULL;
+
+ return prev_ioloop;
+}
+
+struct ioloop *
+http_server_connection_switch_ioloop(struct http_server_connection *conn)
+{
+ return http_server_connection_switch_ioloop_to(conn, current_ioloop);
}
struct http_server_payload_handler {
struct http_server_request *req;
- void (*switch_ioloop)(struct http_server_payload_handler *handler);
+ void (*switch_ioloop)(struct http_server_payload_handler *handler,
+ struct ioloop *ioloop);
void (*destroy)(struct http_server_payload_handler *handler);
bool in_callback:1;
struct http_server_connection {
struct connection conn;
struct http_server *server;
+ struct ioloop *ioloop, *ioloop_switching;
struct event *event;
unsigned int refcount;
bool input_broken:1;
bool output_locked:1;
bool in_req_callback:1; /* performing request callback (busy) */
- bool switching_ioloop:1; /* in the middle of switching ioloop */
};
struct http_server_location {
void http_server_payload_handler_destroy(
struct http_server_payload_handler **_handler);
void http_server_payload_handler_switch_ioloop(
- struct http_server_payload_handler *handler);
+ struct http_server_payload_handler *handler, struct ioloop *ioloop);
/*
* Connection
bool http_server_connection_shut_down(struct http_server_connection *conn);
-void http_server_connection_switch_ioloop(struct http_server_connection *conn);
-
void http_server_connection_handle_output_error(
struct http_server_connection *conn);
}
void http_server_payload_handler_switch_ioloop(
- struct http_server_payload_handler *handler)
+ struct http_server_payload_handler *handler, struct ioloop *ioloop)
{
if (handler->switch_ioloop != NULL)
- handler->switch_ioloop(handler);
+ handler->switch_ioloop(handler, ioloop);
}
/* Pump-based */
}
static void
-payload_handler_pump_switch_ioloop(struct http_server_payload_handler *handler)
+payload_handler_pump_switch_ioloop(struct http_server_payload_handler *handler,
+ struct ioloop *ioloop)
{
struct http_server_payload_handler_pump *phandler =
(struct http_server_payload_handler_pump *)handler;
- iostream_pump_switch_ioloop(phandler->pump);
+ iostream_pump_switch_ioloop_to(phandler->pump, ioloop);
}
static void
}
static void
-payload_handler_raw_switch_ioloop(struct http_server_payload_handler *handler)
+payload_handler_raw_switch_ioloop(struct http_server_payload_handler *handler,
+ struct ioloop *ioloop)
{
struct http_server_payload_handler_raw *rhandler =
(struct http_server_payload_handler_raw *)handler;
- rhandler->io = io_loop_move_io(&rhandler->io);
+ rhandler->io = io_loop_move_io_to(ioloop, &rhandler->io);
}
static void
const struct http_server_stats *
http_server_connection_get_stats(struct http_server_connection *conn);
+/* Switch connection to a specific ioloop. */
+struct ioloop *
+http_server_connection_switch_ioloop_to(struct http_server_connection *conn,
+ struct ioloop *ioloop);
+/* Switch connection to the current ioloop. */
+struct ioloop *
+http_server_connection_switch_ioloop(struct http_server_connection *conn);
+
/*
* Resource
*/