]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dict: Use connection API
authorAki Tuomi <aki.tuomi@open-xchange.com>
Sun, 31 Mar 2019 13:54:28 +0000 (16:54 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 1 Apr 2019 15:06:57 +0000 (18:06 +0300)
src/dict/dict-commands.c
src/dict/dict-connection.c
src/dict/dict-connection.h
src/dict/main.c

index 77e8f0e5b32d6e8d34571216b87ba6b6696e1cf0..915336b2153abb9f68cdae7c22714327418e8fd1 100644 (file)
@@ -52,7 +52,7 @@ static void dict_connection_cmd_free(struct dict_connection_cmd *cmd)
        i_free(cmd->reply);
 
        if (dict_connection_unref(cmd->conn))
-               dict_connection_continue_input(cmd->conn);
+               connection_input_resume(&cmd->conn->conn);
        i_free(cmd);
 }
 
@@ -282,9 +282,7 @@ static void cmd_iterate_callback(void *context)
        struct dict_connection *conn = cmd->conn;
 
        dict_connection_ref(conn);
-       o_stream_cork(conn->conn.output);
        dict_connection_cmd_output_more(cmd);
-       o_stream_uncork(conn->conn.output);
        dict_connection_unref_safe(conn);
 }
 
index 4545d91ead383761186be69725d503f102ca1426..62bceb09cf7e614b37b928d6a48955884d80be1a 100644 (file)
 
 #define DICT_CONN_MAX_PENDING_COMMANDS 1000
 
-static struct dict_connection *dict_connections;
-static unsigned int dict_connections_count = 0;
+static int dict_connection_dict_init(struct dict_connection *conn);
+static void dict_connection_destroy(struct connection *_conn);
+struct connection_list *dict_connections = NULL;
 
-static int dict_connection_parse_handshake(struct dict_connection *conn,
+static int dict_connection_parse_handshake(struct connection *_conn,
                                           const char *line)
 {
+       struct dict_connection *conn =
+               container_of(_conn, struct dict_connection, conn);
        const char *username, *name, *value_type;
        unsigned int value_type_num;
 
@@ -68,7 +71,10 @@ static int dict_connection_parse_handshake(struct dict_connection *conn,
                return -1;
 
        conn->name = i_strdup(name);
-       return 0;
+       if (dict_connection_dict_init(conn) < 0)
+               return -1;
+
+       return 1;
 }
 
 static int dict_connection_dict_init(struct dict_connection *conn)
@@ -108,86 +114,13 @@ static int dict_connection_dict_init(struct dict_connection *conn)
        return 0;
 }
 
-static void dict_connection_input_more(struct connection *_conn)
-{
-       struct dict_connection *conn = container_of(_conn, struct dict_connection, conn);
-       const char *line;
-       int ret;
-
-       timeout_remove(&conn->to_input);
-
-       while ((line = i_stream_next_line(conn->conn.input)) != NULL) {
-               T_BEGIN {
-                       ret = dict_command_input(conn, line);
-               } T_END;
-               if (ret < 0) {
-                       dict_connection_destroy(conn);
-                       break;
-               }
-               if (array_count(&conn->cmds) >= DICT_CONN_MAX_PENDING_COMMANDS) {
-                       io_remove(&conn->conn.io);
-                       timeout_remove(&conn->to_input);
-                       break;
-               }
-       }
-}
-
-static void dict_connection_input(struct connection *_conn)
-{
-       struct dict_connection *conn = container_of(_conn, struct dict_connection, conn);
-       const char *line;
-
-       switch (i_stream_read(conn->conn.input)) {
-       case 0:
-               return;
-       case -1:
-               /* disconnected */
-               dict_connection_destroy(conn);
-               return;
-       case -2:
-               /* buffer full */
-               i_error("dict client: Sent us more than %d bytes",
-                       (int)DICT_CLIENT_MAX_LINE_LENGTH);
-               dict_connection_destroy(conn);
-               return;
-       }
-
-       if (conn->username == NULL) {
-               /* handshake not received yet */
-               if ((line = i_stream_next_line(conn->conn.input)) == NULL)
-                       return;
-
-               if (dict_connection_parse_handshake(conn, line) < 0) {
-                       i_error("dict client: Broken handshake");
-                       dict_connection_destroy(conn);
-                       return;
-               }
-               if (dict_connection_dict_init(conn) < 0) {
-                       dict_connection_destroy(conn);
-                       return;
-               }
-       }
-
-       dict_connection_input_more(&conn->conn);
-}
-
-void dict_connection_continue_input(struct dict_connection *conn)
-{
-       if (conn->conn.io != NULL || conn->destroyed)
-               return;
-
-       conn->conn.io = io_add(conn->conn.fd_in, IO_READ, dict_connection_input, &conn->conn);
-       if (conn->to_input == NULL)
-               conn->to_input = timeout_add_short(0, dict_connection_input_more, &conn->conn);
-}
-
 static int dict_connection_output(struct connection *_conn)
 {
        struct dict_connection *conn = container_of(_conn, struct dict_connection, conn);
        int ret;
 
        if ((ret = o_stream_flush(conn->conn.output)) < 0) {
-               dict_connection_destroy(conn);
+               dict_connection_destroy(&conn->conn);
                return 1;
        }
        if (ret > 0)
@@ -202,16 +135,15 @@ dict_connection_create(struct master_service_connection *master_conn)
 
        conn = i_new(struct dict_connection, 1);
        conn->refcount = 1;
-       conn->conn.fd_in = conn->conn.fd_out = master_conn->fd;
-       conn->conn.input = i_stream_create_fd(conn->conn.fd_in, DICT_CLIENT_MAX_LINE_LENGTH);
-       conn->conn.output = o_stream_create_fd(conn->conn.fd_out, 128*1024);
-       o_stream_set_no_error_handling(conn->conn.output, TRUE);
-       o_stream_set_flush_callback(conn->conn.output, dict_connection_output, &conn->conn);
-       conn->conn.io = io_add(conn->conn.fd_in, IO_READ, dict_connection_input, &conn->conn);
+
+       connection_init_server(dict_connections, &conn->conn, master_conn->name,
+                              master_conn->fd, master_conn->fd);
+
+       o_stream_set_flush_callback(conn->conn.output, dict_connection_output,
+                                   &conn->conn);
+
        i_array_init(&conn->cmds, DICT_CONN_MAX_PENDING_COMMANDS);
 
-       dict_connections_count++;
-       DLLIST_PREPEND(&dict_connections, conn);
        return conn;
 }
 
@@ -246,10 +178,10 @@ bool dict_connection_unref(struct dict_connection *conn)
        if (array_is_created(&conn->transactions))
                array_free(&conn->transactions);
 
-       i_stream_destroy(&conn->conn.input);
-       o_stream_destroy(&conn->conn.output);
-
        array_free(&conn->cmds);
+
+       connection_deinit(&conn->conn);
+
        i_free(conn->name);
        i_free(conn->username);
        i_free(conn);
@@ -258,6 +190,24 @@ bool dict_connection_unref(struct dict_connection *conn)
        return FALSE;
 }
 
+static int dict_connection_input_line(struct connection *_conn, const char *line)
+{
+       struct dict_connection *conn =
+               container_of(_conn, struct dict_connection, conn);
+
+       i_assert(conn->dict != NULL);
+
+       if (dict_command_input(conn, line) < 0)
+               return -1;
+
+       if (array_count(&conn->cmds) >= DICT_CONN_MAX_PENDING_COMMANDS) {
+               connection_input_halt(_conn);
+               return 0;
+       }
+
+       return 1;
+}
+
 static void dict_connection_unref_safe_callback(struct dict_connection *conn)
 {
        timeout_remove(&conn->to_unref);
@@ -279,24 +229,9 @@ void dict_connection_unref_safe(struct dict_connection *conn)
        }
 }
 
-void dict_connection_destroy(struct dict_connection *conn)
+static void dict_connection_destroy(struct connection *_conn)
 {
-       i_assert(!conn->destroyed);
-       i_assert(conn->to_unref == NULL);
-
-       i_assert(dict_connections_count > 0);
-       dict_connections_count--;
-
-       conn->destroyed = TRUE;
-       DLLIST_REMOVE(&dict_connections, conn);
-
-       timeout_remove(&conn->to_input);
-       io_remove(&conn->conn.io);
-       i_stream_close(conn->conn.input);
-       o_stream_close(conn->conn.output);
-       i_close_fd(&conn->conn.fd_in);
-       conn->conn.fd_out = -1;
-
+       struct dict_connection *conn = container_of(_conn, struct dict_connection, conn);
        /* the connection is closed, but there may still be commands left
           running. finish them, even if the calling client can't be notified
           about whether they succeeded (clients may not even care).
@@ -304,17 +239,33 @@ void dict_connection_destroy(struct dict_connection *conn)
           flush the command output here in case we were waiting on iteration
           output. */
        dict_connection_cmds_output_more(conn);
-
-       dict_connection_unref(conn);
+       dict_connection_unref_safe(conn);
 }
 
 unsigned int dict_connections_current_count(void)
 {
-       return dict_connections_count;
+       return dict_connections->connections_count;
 }
 
 void dict_connections_destroy_all(void)
 {
-       while (dict_connections != NULL)
-               dict_connection_destroy(dict_connections);
+       connection_list_deinit(&dict_connections);
+}
+
+static struct connection_settings dict_connections_set = {
+       .dont_send_version = TRUE,
+       .input_max_size = DICT_CLIENT_MAX_LINE_LENGTH,
+       .output_max_size = 128*1024,
+};
+
+static struct connection_vfuncs dict_connections_vfuncs = {
+       .destroy = dict_connection_destroy,
+       .handshake_line = dict_connection_parse_handshake,
+       .input_line = dict_connection_input_line,
+};
+
+void dict_connections_init(void)
+{
+       dict_connections = connection_list_init(&dict_connections_set,
+                                               &dict_connections_vfuncs);
 }
index 39ad421bb03db2c24478fbdadbf23ef3c01fea55..3eba772fe2b85f4a50ea17a7ff682dc522536124 100644 (file)
@@ -21,7 +21,6 @@ struct dict_connection {
        struct dict *dict;
        enum dict_data_type value_type;
 
-       struct timeout *to_input;
        struct timeout *to_unref;
 
        /* There are only a few transactions per client, so keeping them in
@@ -29,23 +28,19 @@ struct dict_connection {
        ARRAY(struct dict_connection_transaction) transactions;
        ARRAY(struct dict_connection_cmd *) cmds;
        unsigned int async_id_counter;
-
-       bool destroyed:1;
 };
 
 struct master_service_connection;
 
 struct dict_connection *
 dict_connection_create(struct master_service_connection *master_conn);
-void dict_connection_destroy(struct dict_connection *conn);
 
 void dict_connection_ref(struct dict_connection *conn);
 bool dict_connection_unref(struct dict_connection *conn);
 void dict_connection_unref_safe(struct dict_connection *conn);
 
-void dict_connection_continue_input(struct dict_connection *conn);
-
 unsigned int dict_connections_current_count(void);
+void dict_connections_init(void);
 void dict_connections_destroy_all(void);
 
 #endif
index 621e264c9c4578bc0e0028cbf8623b0aeac2b69c..6a9f3df534fdadf500314cf89b1b102601c5a69b 100644 (file)
@@ -111,6 +111,7 @@ static void main_init(void)
           which we'll need to register. */
        dict_drivers_register_all();
        dict_commands_init();
+       dict_connections_init();
 }
 
 static void main_deinit(void)