struct master_login_connection *conns;
struct master_login_auth *auth;
char *postlogin_socket_path;
+
+ unsigned int stopping:1;
};
static void master_login_conn_deinit(struct master_login_connection **_conn);
login->callback = callback;
login->auth = master_login_auth_init(auth_socket_path);
login->postlogin_socket_path = i_strdup(postlogin_socket_path);
- service->login_connections = TRUE;
+
+ i_assert(service->login == NULL);
+ service->login = login;
return login;
}
*_login = NULL;
+ i_assert(login->service->login == login);
+ login->service->login = NULL;
+
master_login_auth_deinit(&login->auth);
while (login->conns != NULL) {
struct master_login_connection *conn = login->conns;
const char *const *auth_args)
{
struct master_login_connection *conn = client->conn;
- struct master_service *service = conn->login->service;
- bool close_config;
+ struct master_login *login = conn->login;
+ struct master_service *service = login->service;
+ bool close_sockets;
- close_config = service->master_status.available_count == 0 &&
+ close_sockets = service->master_status.available_count == 0 &&
service->service_count_left == 1;
- conn->login->callback(client, auth_args[0], auth_args+1);
+ login->callback(client, auth_args[0], auth_args+1);
i_free(client);
- if (close_config) {
+ if (close_sockets) {
/* we're dying as soon as this connection closes. */
+ i_assert(master_login_auth_request_count(login->auth) == 0);
+ master_login_auth_disconnect(login->auth);
+
master_service_close_config_fd(service);
master_login_conn_deinit(&conn);
+ } else if (login->stopping) {
+ /* try stopping again */
+ master_login_stop(login);
}
}
master_service_io_listeners_add(conn->login->service);
i_free(conn);
}
+
+void master_login_stop(struct master_login *login)
+{
+ login->stopping = TRUE;
+ if (master_login_auth_request_count(login->auth) == 0) {
+ master_login_auth_disconnect(login->auth);
+ master_service_close_config_fd(login->service);
+ }
+}
void (*avail_overflow_callback)(void);
struct timeout *to_overflow_state;
+ struct master_login *login;
+
master_service_connection_callback_t *callback;
pool_t set_pool;
unsigned int die_with_master:1;
unsigned int call_avail_overflow:1;
unsigned int delay_status_updates:1;
- /* incoming connections are going to master-login and they're not
- counted as real connections */
- unsigned int login_connections:1;
};
void master_service_io_listeners_add(struct master_service *service);
#include "fd-close-on-exec.h"
#include "settings-parser.h"
#include "syslog-util.h"
+#include "master-login.h"
#include "master-service-private.h"
#include "master-service-settings.h"
service->master_status.available_count = 0;
master_status_update(service);
}
+ if (service->login != NULL)
+ master_login_stop(service->login);
}
void master_service_anvil_send(struct master_service *service, const char *cmd)
conn.ssl = l->ssl;
net_set_nonblock(conn.fd, TRUE);
- if (!service->login_connections) {
+ if (service->login != NULL) {
+ /* incoming connections are going to master-login and they're
+ not counted as real connections */
+ } else {
i_assert(service->master_status.available_count > 0);
service->master_status.available_count--;
master_status_update(service);