From: Stephan Bosch Date: Sat, 9 Nov 2019 09:47:22 +0000 (+0100) Subject: lib-http: http-server-connection - Add support for switching to an explicit ioloop. X-Git-Tag: 2.3.11.2~293 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1453b57ef141a767d54aa77c219e6edc1b1eab82;p=thirdparty%2Fdovecot%2Fcore.git lib-http: http-server-connection - Add support for switching to an explicit ioloop. --- diff --git a/src/lib-http/http-server-connection.c b/src/lib-http/http-server-connection.c index d1bb19a5a7..06a22f5c06 100644 --- a/src/lib-http/http-server-connection.c +++ b/src/lib-http/http-server-connection.c @@ -1033,6 +1033,7 @@ http_server_connection_create(struct http_server *server, 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; @@ -1196,22 +1197,43 @@ void http_server_connection_tunnel(struct http_server_connection **_conn, 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); } diff --git a/src/lib-http/http-server-private.h b/src/lib-http/http-server-private.h index e939ab5051..82fad79022 100644 --- a/src/lib-http/http-server-private.h +++ b/src/lib-http/http-server-private.h @@ -55,7 +55,8 @@ enum http_server_request_state { 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; @@ -127,6 +128,7 @@ struct http_server_request { struct http_server_connection { struct connection conn; struct http_server *server; + struct ioloop *ioloop, *ioloop_switching; struct event *event; unsigned int refcount; @@ -155,7 +157,6 @@ struct http_server_connection { 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 { @@ -248,7 +249,7 @@ void http_server_request_finished(struct http_server_request *req); 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 @@ -275,8 +276,6 @@ struct connection_list *http_server_connection_list_init(void); 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); diff --git a/src/lib-http/http-server-request.c b/src/lib-http/http-server-request.c index f266ab9c3e..c5c31300b7 100644 --- a/src/lib-http/http-server-request.c +++ b/src/lib-http/http-server-request.c @@ -702,10 +702,10 @@ void http_server_payload_handler_destroy( } 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 */ @@ -729,12 +729,13 @@ payload_handler_pump_destroy(struct http_server_payload_handler *handler) } 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 @@ -875,12 +876,13 @@ payload_handler_raw_destroy(struct http_server_payload_handler *handler) } 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 diff --git a/src/lib-http/http-server.h b/src/lib-http/http-server.h index fce35eed6c..bbd33a5535 100644 --- a/src/lib-http/http-server.h +++ b/src/lib-http/http-server.h @@ -351,6 +351,14 @@ void http_server_connection_close(struct http_server_connection **_conn, 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 */