conn->request_queue_count,
conn->server->set.max_pipelined_requests);
- http_server_request_ref(req);
- i_assert(!req->delay_destroy);
- req->delay_destroy = TRUE;
+ http_server_request_immune_ref(req);
T_BEGIN {
cont = http_server_connection_handle_request(conn, req);
} T_END;
- req->delay_destroy = FALSE;
if (!cont) {
/* Connection closed or request body not read
yet. The request may be destroyed now. */
- if (req->destroy_pending)
- http_server_request_destroy(&req);
- else
- http_server_request_unref(&req);
+ http_server_request_immune_unref(&req);
http_server_connection_unref(&conn);
return;
}
if (req->req.connection_close)
conn->close_indicated = TRUE;
- if (req->destroy_pending)
- http_server_request_destroy(&req);
- else
- http_server_request_unref(&req);
+ http_server_request_immune_unref(&req);
if (conn->closed) {
/* Connection got closed in destroy callback */
struct http_server_request {
struct http_request req;
pool_t pool;
- unsigned int refcount;
+ unsigned int refcount, immune_refcount;
unsigned int id;
int callback_refcount;
struct event *event;
bool payload_halted:1;
bool sent_100_continue:1;
- bool delay_destroy:1;
bool destroy_pending:1;
bool failed:1;
bool connection_close:1;
void http_server_request_abort(struct http_server_request **_req,
const char *reason) ATTR_NULL(2);
+void http_server_request_immune_ref(struct http_server_request *req);
+void http_server_request_immune_unref(struct http_server_request **_req);
+
bool http_server_request_is_complete(struct http_server_request *req);
void http_server_request_callback(struct http_server_request *req);
if (server->ioloop != NULL)
io_loop_stop(server->ioloop);
- if (req->delay_destroy) {
+ if (req->immune_refcount > 0) {
req->destroy_pending = TRUE;
http_server_request_unref(_req);
return;
http_server_request_destroy(_req);
}
+void http_server_request_immune_ref(struct http_server_request *req)
+{
+ http_server_request_ref(req);
+ req->immune_refcount++;
+}
+
+void http_server_request_immune_unref(struct http_server_request **_req)
+{
+ struct http_server_request *req = *_req;
+
+ i_assert(req->immune_refcount > 0);
+
+ *_req = NULL;
+ if (--req->immune_refcount == 0 && req->destroy_pending)
+ http_server_request_destroy(&req);
+ else
+ http_server_request_unref(&req);
+}
+
const struct http_request *
http_server_request_get(struct http_server_request *req)
{