From 442232f2d1cfdf28f3a18aa00a5c19246d321036 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Mon, 26 Oct 2009 23:41:54 -0400 Subject: [PATCH] lib-master: Fixes to handling master-login services. --HG-- branch : HEAD --- src/lib-master/master-login-auth.c | 5 +++++ src/lib-master/master-login-auth.h | 1 + src/lib-master/master-login.c | 24 +++++++++++++++++++----- src/lib-master/master-service-private.h | 2 ++ src/lib-master/master-service.c | 10 +++++----- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/lib-master/master-login-auth.c b/src/lib-master/master-login-auth.c index 4ed0be373b..8d15a9f9ec 100644 --- a/src/lib-master/master-login-auth.c +++ b/src/lib-master/master-login-auth.c @@ -288,3 +288,8 @@ void master_login_auth_request(struct master_login_auth *auth, login_req->context = context; hash_table_insert(auth->requests, POINTER_CAST(id), login_req); } + +unsigned int master_login_auth_request_count(struct master_login_auth *auth) +{ + return hash_table_count(auth->requests); +} diff --git a/src/lib-master/master-login-auth.h b/src/lib-master/master-login-auth.h index 3db896d6bd..7dd485ae0a 100644 --- a/src/lib-master/master-login-auth.h +++ b/src/lib-master/master-login-auth.h @@ -14,5 +14,6 @@ void master_login_auth_request(struct master_login_auth *auth, const struct master_auth_request *req, master_login_auth_request_callback_t *callback, void *context); +unsigned int master_login_auth_request_count(struct master_login_auth *auth); #endif diff --git a/src/lib-master/master-login.c b/src/lib-master/master-login.c index 56138524fb..50629e7b85 100644 --- a/src/lib-master/master-login.c +++ b/src/lib-master/master-login.c @@ -131,7 +131,8 @@ master_login_auth_callback(const char *const *auth_args, void *context) { struct master_login_client *client = context; struct master_auth_reply reply; - struct master_service *service = client->conn->login->service; + struct master_login_connection *conn = client->conn; + struct master_service *service = conn->login->service; bool close_config; memset(&reply, 0, sizeof(reply)); @@ -139,7 +140,7 @@ master_login_auth_callback(const char *const *auth_args, void *context) reply.status = auth_args != NULL ? MASTER_AUTH_STATUS_OK : MASTER_AUTH_STATUS_INTERNAL_ERROR; reply.mail_pid = getpid(); - o_stream_send(client->conn->output, &reply, sizeof(reply)); + o_stream_send(conn->output, &reply, sizeof(reply)); if (auth_args == NULL) { if (close(client->fd) < 0) @@ -148,17 +149,19 @@ master_login_auth_callback(const char *const *auth_args, void *context) return; } + i_assert(service->master_status.available_count > 0); service->master_status.available_count--; master_status_update(service); close_config = service->master_status.available_count == 0 && service->service_count_left == 1; - client->conn->login->callback(client, auth_args[0], auth_args+1); + conn->login->callback(client, auth_args[0], auth_args+1); i_free(client); if (close_config) { /* we're dying as soon as this connection closes. */ master_service_close_config_fd(service); + master_login_conn_deinit(&conn); } } @@ -166,7 +169,9 @@ static void master_login_conn_input(struct master_login_connection *conn) { struct master_auth_request req; struct master_login_client *client; + struct master_login *login = conn->login; unsigned char data[MASTER_AUTH_MAX_DATA_SIZE]; + unsigned int request_count; int ret, client_fd; ret = master_login_conn_read_request(conn, &req, data, &client_fd); @@ -188,8 +193,11 @@ static void master_login_conn_input(struct master_login_connection *conn) client->auth_req = req; memcpy(client->data, data, req.data_size); - master_login_auth_request(conn->login->auth, &req, + master_login_auth_request(login->auth, &req, master_login_auth_callback, client); + request_count = master_login_auth_request_count(login->auth); + if (login->service->master_status.available_count <= request_count) + io_remove(&conn->io); } void master_login_add(struct master_login *login, int fd) @@ -203,6 +211,10 @@ void master_login_add(struct master_login *login, int fd) conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); DLLIST_PREPEND(&login->conns, conn); + + /* don't accept more connections. this is mainly a temporary + workaround.. */ + master_service_io_listeners_remove(login->service); } static void master_login_conn_deinit(struct master_login_connection **_conn) @@ -213,9 +225,11 @@ static void master_login_conn_deinit(struct master_login_connection **_conn) DLLIST_REMOVE(&conn->login->conns, conn); - io_remove(&conn->io); + if (conn->io != NULL) + io_remove(&conn->io); o_stream_unref(&conn->output); if (close(conn->fd) < 0) i_error("close(master login) failed: %m"); + master_service_io_listeners_add(conn->login->service); i_free(conn); } diff --git a/src/lib-master/master-service-private.h b/src/lib-master/master-service-private.h index ff64a00d46..2ba018fb2f 100644 --- a/src/lib-master/master-service-private.h +++ b/src/lib-master/master-service-private.h @@ -62,4 +62,6 @@ void master_service_io_listeners_add(struct master_service *service); void master_status_update(struct master_service *service); void master_service_close_config_fd(struct master_service *service); +void master_service_io_listeners_remove(struct master_service *service); + #endif diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index a64e4e978a..cc3e36310a 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -39,7 +39,6 @@ struct master_service *master_service; static void master_service_refresh_login_state(struct master_service *service); -static void io_listeners_remove(struct master_service *service); const char *master_service_getopt_string(void) { @@ -265,7 +264,7 @@ bool master_service_parse_option(struct master_service *service, static void master_service_error(struct master_service *service) { - io_listeners_remove(service); + master_service_io_listeners_remove(service); if (service->master_status.available_count == service->total_available_count || service->die_with_master) { if (service->die_callback == NULL) @@ -585,7 +584,7 @@ void master_service_deinit(struct master_service **_service) *_service = NULL; - io_listeners_remove(service); + master_service_io_listeners_remove(service); master_service_close_config_fd(service); if (service->to_die != NULL) @@ -631,7 +630,7 @@ static void master_service_listen(struct master_service_listener *l) } if (service->master_status.available_count == 0) { - io_listeners_remove(service); + master_service_io_listeners_remove(service); return; } } @@ -663,6 +662,7 @@ static void master_service_listen(struct master_service_listener *l) if (service->login_connections) close_config = FALSE; else { + i_assert(service->master_status.available_count > 0); service->master_status.available_count--; master_status_update(service); close_config = service->master_status.available_count == 0 && @@ -715,7 +715,7 @@ void master_service_io_listeners_add(struct master_service *service) } } -static void io_listeners_remove(struct master_service *service) +void master_service_io_listeners_remove(struct master_service *service) { unsigned int i; -- 2.47.3