ARRAY(struct auth_master_request_destroy_callback) destroy_callbacks;
bool sent:1;
+ bool invalid:1;
bool aborted:1;
bool removed:1;
bool in_callback:1;
const char *auth_socket_path;
enum auth_master_flags flags;
- struct timeout *to_connect, *to_idle, *to_request;
+ struct timeout *to_connect, *to_idle, *to_request, *to_invalid;
struct ioloop *ioloop, *prev_ioloop;
unsigned int id_counter;
void auth_master_request_fail(struct auth_master_request **_req,
const char *reason);
+void auth_master_request_abort_invalid(struct auth_master_request **_req);
+
+struct auth_master_request *
+auth_master_request_invalid(struct auth_master_connection *conn,
+ auth_master_request_callback_t *callback,
+ void *context);
+#define auth_master_request_invalid(conn, callback, context) \
+ auth_master_request_invalid(conn, \
+ (auth_master_request_callback_t *)callback, context)
/*
* Connection
void auth_master_connection_start_timeout(struct auth_master_connection *conn);
void auth_master_handle_requests(struct auth_master_connection *conn);
+void auth_master_handle_invalid_requests(struct auth_master_connection *conn);
#endif
auth_master_request_abort(_req);
}
+void auth_master_request_abort_invalid(struct auth_master_request **_req)
+{
+ struct auth_master_request *req = *_req;
+
+ if (req->in_callback)
+ return;
+
+ e_debug(req->event, "Aborted as invalid");
+
+ const struct auth_master_reply mreply = {
+ .reply = "NOTFOUND",
+ };
+
+ i_assert(req->callback != NULL);
+ (void)auth_master_request_callback(req, &mreply);
+
+ auth_master_request_abort(_req);
+}
+
void auth_master_request_send(struct auth_master_request *req)
{
struct auth_master_connection *conn = req->conn;
const char *id_str = dec2str(req->id);
i_assert(req->state == AUTH_MASTER_REQUEST_STATE_SUBMITTED);
+ i_assert(!req->invalid);
const struct const_iovec iov[] = {
{ req->cmd, strlen(req->cmd), },
e_debug(req->event, "Sent");
}
-#undef auth_master_request
-struct auth_master_request *
-auth_master_request(struct auth_master_connection *conn, const char *cmd,
- const unsigned char *args, size_t args_size,
- auth_master_request_callback_t *callback, void *context)
+static struct auth_master_request *
+auth_master_request_new(struct auth_master_connection *conn,
+ auth_master_request_callback_t *callback, void *context)
{
pool_t pool;
struct auth_master_request *req;
- pool = pool_alloconly_create("auth_master_request", 256 + args_size);
+ pool = pool_alloconly_create("auth_master_request", 1024);
req = p_new(pool, struct auth_master_request, 1);
req->pool = pool;
req->refcount = 1;
if (conn->requests_unsent == NULL)
conn->requests_unsent = conn->requests_tail;
- auth_master_connection_start_timeout(conn);
- auth_master_stop_idle(conn);
+ e_debug(req->event, "Created");
+ return req;
+}
+
+#undef auth_master_request
+struct auth_master_request *
+auth_master_request(struct auth_master_connection *conn, const char *cmd,
+ const unsigned char *args, size_t args_size,
+ auth_master_request_callback_t *callback, void *context)
+{
+ struct auth_master_request *req;
+
+ req = auth_master_request_new(conn, callback, context);
req->cmd = p_strdup(req->pool, cmd);
if (args_size > 0)
req->args = p_memdup(req->pool, args, args_size);
req->args_size = args_size;
- e_debug(req->event, "Created");
-
auth_master_handle_requests(conn);
+ auth_master_connection_start_timeout(conn);
+ auth_master_stop_idle(conn);
+ return req;
+}
+
+#undef auth_master_request_invalid
+struct auth_master_request *
+auth_master_request_invalid(struct auth_master_connection *conn,
+ auth_master_request_callback_t *callback,
+ void *context)
+{
+ struct auth_master_request *req;
+
+ req = auth_master_request_new(conn, callback, context);
+ req->invalid = TRUE;
+
+ auth_master_handle_invalid_requests(conn);
return req;
}
timeout_remove(&conn->to_connect);
timeout_remove(&conn->to_request);
timeout_remove(&conn->to_idle);
+ timeout_remove(&conn->to_invalid);
while (conn->requests_head != NULL) {
req = conn->requests_head;
o_stream_set_flush_pending(conn->conn.output, TRUE);
}
+static void
+auth_master_abort_invalid_requests(struct auth_master_connection *conn)
+{
+ struct auth_master_request *req, *req_next;
+
+ timeout_remove(&conn->to_invalid);
+
+ req = conn->requests_unsent;
+ while (req != NULL) {
+ req_next = req->next;
+ if (req->invalid)
+ auth_master_request_abort_invalid(&req);
+ req = req_next;
+ }
+}
+
+void auth_master_handle_invalid_requests(struct auth_master_connection *conn)
+{
+ if (conn->to_invalid != NULL)
+ return;
+
+ conn->to_invalid = timeout_add_to(
+ conn->ioloop, 0,
+ auth_master_abort_invalid_requests, conn);
+}
+
void auth_master_switch_ioloop_to(struct auth_master_connection *conn,
struct ioloop *ioloop)
{
}
if (conn->to_idle != NULL)
conn->to_idle = io_loop_move_timeout_to(ioloop, &conn->to_idle);
+ if (conn->to_invalid != NULL) {
+ conn->to_idle =
+ io_loop_move_timeout_to(ioloop, &conn->to_invalid);
+ }
connection_switch_ioloop_to(&conn->conn, conn->ioloop);
}