]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: http-server-connection - Add support for switching to an explicit ioloop.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Sat, 9 Nov 2019 09:47:22 +0000 (10:47 +0100)
committermartti.rannanjarvi <martti.rannanjarvi@open-xchange.com>
Sat, 18 Apr 2020 14:55:11 +0000 (14:55 +0000)
src/lib-http/http-server-connection.c
src/lib-http/http-server-private.h
src/lib-http/http-server-request.c
src/lib-http/http-server.h

index d1bb19a5a71583d6689abbebc4be1a5b965cf527..06a22f5c06951292e36f997ea272fb59acc36d31 100644 (file)
@@ -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);
 }
index e939ab5051cdf3ceeb12792cd3fc3a3ee87ff077..82fad790224af9d3475bd1c38b68cc8b1e72b61d 100644 (file)
@@ -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);
 
index f266ab9c3e6d82ab0e52359ad02752eb15fe20f6..c5c31300b77bdc2a8a39bb053f212017a1132404 100644 (file)
@@ -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
index fce35eed6c5c28effe6047b19fec2e9b4efebc09..bbd33a5535cbf26aab724ce39f8535185e7c58a3 100644 (file)
@@ -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
  */