Mercurial > dovecot > original-hg > dovecot-1.2
changeset 3307:38754475d3b6 HEAD
Exit only if all master connections are lost, not only if one of them is.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 19 Apr 2005 09:54:41 +0300 |
parents | aebed9a9edac |
children | 3f090bcaffcc |
files | src/auth/auth-master-connection.c src/auth/auth-master-connection.h src/auth/main.c |
diffstat | 3 files changed, 69 insertions(+), 64 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-master-connection.c Sun Apr 17 19:52:00 2005 +0300 +++ b/src/auth/auth-master-connection.c Tue Apr 19 09:54:41 2005 +0300 @@ -34,9 +34,10 @@ struct auth_request *auth_request; }; +static array_t ARRAY_DEFINE(master_connections, + struct auth_master_connection *); + static int master_output(void *context); -static void auth_master_connection_close(struct auth_master_connection *conn); -static int auth_master_connection_unref(struct auth_master_connection *conn); static void auth_listener_destroy(struct auth_listener *l); void auth_master_request_callback(const char *reply, void *context) @@ -141,13 +142,13 @@ return; case -1: /* disconnected */ - auth_master_connection_close(conn); + auth_master_connection_destroy(conn); return; case -2: /* buffer full */ i_error("BUG: Master sent us more than %d bytes", (int)MAX_INBUF_SIZE); - auth_master_connection_close(conn); + auth_master_connection_destroy(conn); return; } @@ -162,7 +163,7 @@ AUTH_MASTER_PROTOCOL_MAJOR_VERSION) { i_error("Master not compatible with this server " "(mixed old and new binaries?)"); - auth_master_connection_close(conn); + auth_master_connection_destroy(conn); return; } conn->version_received = TRUE; @@ -186,7 +187,7 @@ t_pop(); if (!ret) { - auth_master_connection_close(conn); + auth_master_connection_destroy(conn); return; } } @@ -199,7 +200,7 @@ if ((ret = o_stream_flush(conn->output)) < 0) { /* transmit error, probably master died */ - auth_master_connection_close(conn); + auth_master_connection_destroy(conn); return 1; } @@ -237,12 +238,12 @@ conn = i_new(struct auth_master_connection, 1); conn->auth = auth; - conn->refcount = 1; conn->pid = (unsigned int)getpid(); conn->fd = fd; conn->listeners_buf = buffer_create_dynamic(default_pool, 64); if (fd != -1) auth_master_connection_set_fd(conn, fd); + array_append(&master_connections, &conn, 1); return conn; } @@ -259,30 +260,11 @@ (void)o_stream_send_str(conn->output, line); } -static void auth_master_connection_close(struct auth_master_connection *conn) -{ - if (!standalone) - io_loop_stop(ioloop); - - if (close(conn->fd) < 0) - i_error("close(): %m"); - conn->fd = -1; - - i_stream_unref(conn->input); - conn->input = NULL; - - o_stream_unref(conn->output); - conn->output = NULL; - - if (conn->io != NULL) { - io_remove(conn->io); - conn->io = NULL; - } -} - void auth_master_connection_destroy(struct auth_master_connection *conn) { + struct auth_master_connection *const *conns; struct auth_listener **l; + unsigned int i, count; if (conn->destroyed) return; @@ -290,8 +272,16 @@ auth_client_connections_deinit(conn); - if (conn->fd != -1) - auth_master_connection_close(conn); + if (conn->fd != -1) { + if (close(conn->fd) < 0) + i_error("close(): %m"); + } + if (conn->input != NULL) + i_stream_unref(conn->input); + if (conn->output != NULL) + o_stream_unref(conn->output); + if (conn->io != NULL) + io_remove(conn->io); while (conn->listeners_buf->used > 0) { l = buffer_get_modifyable_data(conn->listeners_buf, NULL); @@ -300,18 +290,17 @@ buffer_free(conn->listeners_buf); conn->listeners_buf = NULL; - auth_master_connection_unref(conn); -} - -static int auth_master_connection_unref(struct auth_master_connection *conn) -{ - if (--conn->refcount > 0) - return TRUE; - - if (conn->output != NULL) - o_stream_unref(conn->output); + conns = array_get(&master_connections, &count); + for (i = 0; i < count; i++) { + if (conns[i] == conn) { + array_delete(&master_connections, i, 1); + break; + } + } + if (!standalone && array_count(&master_connections) == 0) + io_loop_stop(ioloop); + i_free(conn); - return FALSE; } static void auth_accept(void *context) @@ -378,3 +367,30 @@ } i_free(l); } + +void auth_master_connections_send_handshake(void) +{ + struct auth_master_connection *const *conns; + unsigned int i, count; + + conns = array_get(&master_connections, &count); + for (i = 0; i < count; i++) + auth_master_connection_send_handshake(conns[i]); +} + +void auth_master_connections_init(void) +{ + ARRAY_CREATE(&master_connections, default_pool, + struct auth_master_connection *, 16); +} + +void auth_master_connections_deinit(void) +{ + struct auth_master_connection *const *conns; + unsigned int i, count; + + conns = array_get(&master_connections, &count); + for (i = count; i > 0; i--) + auth_master_connection_destroy(conns[i]); + array_free(&master_connections); +}
--- a/src/auth/auth-master-connection.h Sun Apr 17 19:52:00 2005 +0300 +++ b/src/auth/auth-master-connection.h Tue Apr 19 09:54:41 2005 +0300 @@ -29,8 +29,10 @@ struct auth_master_connection * auth_master_connection_create(struct auth *auth, int fd); +void auth_master_connection_destroy(struct auth_master_connection *conn); + void auth_master_connection_send_handshake(struct auth_master_connection *conn); -void auth_master_connection_destroy(struct auth_master_connection *conn); +void auth_master_connections_send_handshake(void); void auth_master_request_callback(const char *reply, void *context); @@ -38,4 +40,7 @@ int fd, const char *path, enum listener_type type); +void auth_master_connections_init(void); +void auth_master_connections_deinit(void); + #endif
--- a/src/auth/main.c Sun Apr 17 19:52:00 2005 +0300 +++ b/src/auth/main.c Tue Apr 19 09:54:41 2005 +0300 @@ -30,7 +30,6 @@ int standalone = FALSE, worker = FALSE; time_t process_start_time; -static buffer_t *masters_buf; static struct auth *auth; static struct auth_worker_client *worker_client; @@ -169,7 +168,6 @@ LISTENER_CLIENT); } auth_client_connections_init(master); - buffer_append(masters_buf, &master, sizeof(master)); t_pop(); } } @@ -186,7 +184,7 @@ auth = auth_preinit(); password_schemes_init(); - masters_buf = buffer_create_dynamic(default_pool, 64); + auth_master_connections_init(); if (!worker) add_extra_listeners(); @@ -196,8 +194,7 @@ static void main_init(int nodaemon) { - struct auth_master_connection *master, **master_p; - size_t i, size; + struct auth_master_connection *master; process_start_time = ioloop_time; lib_init_signals(sig_quit); @@ -243,36 +240,23 @@ auth_master_connection_add_listener(master, CLIENT_LISTEN_FD, NULL, LISTENER_CLIENT); auth_client_connections_init(master); - buffer_append(masters_buf, &master, sizeof(master)); } /* everything initialized, notify masters that all is well */ - master_p = buffer_get_modifyable_data(masters_buf, &size); - size /= sizeof(*master_p); - for (i = 0; i < size; i++) - auth_master_connection_send_handshake(master_p[i]); + auth_master_connections_send_handshake(); } static void main_deinit(void) { - struct auth_master_connection **master; - size_t i, size; - if (lib_signal_kill != 0) i_warning("Killed with signal %d", lib_signal_kill); if (worker_client != NULL) auth_worker_client_destroy(worker_client); - else { + else auth_request_handler_flush_failures(); - master = buffer_get_modifyable_data(masters_buf, &size); - size /= sizeof(*master); - for (i = 0; i < size; i++) - auth_master_connection_destroy(master[i]); - } - buffer_free(masters_buf); - + auth_master_connections_deinit(); auth_request_handler_deinit(); auth_deinit(auth); mech_deinit();