You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kg...@apache.org on 2020/10/15 18:08:20 UTC
[qpid-dispatch] branch dev-protocol-adaptors-2 updated:
DISPATCH-1791: fix strdup and qdr_delivery_t leaks
This is an automated email from the ASF dual-hosted git repository.
kgiusti pushed a commit to branch dev-protocol-adaptors-2
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
The following commit(s) were added to refs/heads/dev-protocol-adaptors-2 by this push:
new 1ec325e DISPATCH-1791: fix strdup and qdr_delivery_t leaks
1ec325e is described below
commit 1ec325e4b1cf0ae5c76bb5cfaa9b88566804a9fd
Author: Kenneth Giusti <kg...@apache.org>
AuthorDate: Wed Oct 14 16:03:50 2020 -0400
DISPATCH-1791: fix strdup and qdr_delivery_t leaks
This closes #882
---
src/adaptors/http1/http1_adaptor.c | 35 ++++++++++++++++++++++++-------
src/adaptors/http1/http1_client.c | 4 ----
src/adaptors/http1/http1_codec.c | 1 +
src/adaptors/http1/http1_private.h | 1 +
src/adaptors/http1/http1_server.c | 43 +++++++++++++++++++++++++-------------
5 files changed, 58 insertions(+), 26 deletions(-)
diff --git a/src/adaptors/http1/http1_adaptor.c b/src/adaptors/http1/http1_adaptor.c
index e1fb155..4cdd44f 100644
--- a/src/adaptors/http1/http1_adaptor.c
+++ b/src/adaptors/http1/http1_adaptor.c
@@ -81,20 +81,36 @@ void qdr_http1_request_base_cleanup(qdr_http1_request_base_t *hreq)
void qdr_http1_connection_free(qdr_http1_connection_t *hconn)
{
if (hconn) {
+ pn_raw_connection_t *rconn = 0;
+ qd_timer_t *t1 = 0;
+ qd_timer_t *t2 = 0;
+ // prevent core from activating this connection while it is being torn
+ // down. see _core_connection_activate_CT
+ //
sys_mutex_lock(qdr_http1_adaptor->lock);
- DEQ_REMOVE(qdr_http1_adaptor->connections, hconn);
+ {
+ DEQ_REMOVE(qdr_http1_adaptor->connections, hconn);
+ t1 = hconn->server.reconnect_timer;
+ hconn->server.reconnect_timer = 0;
+ t2 = hconn->server.activate_timer;
+ hconn->server.activate_timer = 0;
+ rconn = hconn->raw_conn;
+ hconn->raw_conn = 0;
+ }
sys_mutex_unlock(qdr_http1_adaptor->lock);
// request expected to be clean up by caller
#if 0 // JIRA ME!
assert(DEQ_IS_EMPTY(hconn->requests));
#endif
+ qd_timer_free(t1);
+ qd_timer_free(t2);
h1_codec_connection_free(hconn->http_conn);
- if (hconn->raw_conn) {
- pn_raw_connection_set_context(hconn->raw_conn, 0);
- pn_raw_connection_close(hconn->raw_conn);
+ if (rconn) {
+ pn_raw_connection_set_context(rconn, 0);
+ pn_raw_connection_close(rconn);
}
#if 0
if (hconn->out_link) {
@@ -119,8 +135,6 @@ void qdr_http1_connection_free(qdr_http1_connection_t *hconn)
free(hconn->client.client_ip_addr);
free(hconn->client.reply_to_addr);
- qd_timer_free(hconn->server.reconnect_timer);
-
free_qdr_http1_connection_t(hconn);
}
}
@@ -425,12 +439,17 @@ static void _core_connection_activate_CT(void *context, qdr_connection_t *conn)
if (hconn->raw_conn) {
pn_raw_connection_wake(hconn->raw_conn);
activated = true;
+ } else if (hconn->type == HTTP1_CONN_SERVER) {
+ if (hconn->server.activate_timer) {
+ qd_timer_schedule(hconn->server.activate_timer, 0);
+ activated = true;
+ }
}
}
sys_mutex_unlock(qdr_http1_adaptor->lock);
- if (hconn && activated)
- qd_log(qdr_http1_adaptor->log, QD_LOG_DEBUG, "[C%"PRIu64"] Connection activate", hconn->conn_id);
+ qd_log(qdr_http1_adaptor->log, QD_LOG_DEBUG, "[C%"PRIu64"] Connection %s",
+ conn->identity, activated ? "activated" : "down, unable to activate");
}
diff --git a/src/adaptors/http1/http1_client.c b/src/adaptors/http1/http1_client.c
index 3ad9ad6..e1096da 100644
--- a/src/adaptors/http1/http1_client.c
+++ b/src/adaptors/http1/http1_client.c
@@ -228,7 +228,6 @@ qd_http_lsnr_t *qd_http1_configure_listener(qd_dispatch_t *qd, const qd_http_bri
return 0;
}
li->config = *config;
-
DEQ_ITEM_INIT(li);
sys_mutex_lock(qdr_http1_adaptor->lock);
@@ -506,7 +505,6 @@ static void _handle_connection_events(pn_event_t *e, qd_server_t *qd_server, voi
hconn->in_link_credit -= 1;
hreq->request_dlv = qdr_link_deliver(hconn->in_link, hreq->request_msg, 0, false, 0, 0, 0, 0);
qdr_delivery_set_context(hreq->request_dlv, (void*) hreq);
- qdr_delivery_incref(hreq->request_dlv, "referenced by HTTP1 adaptor");
hreq->request_msg = 0;
}
@@ -755,7 +753,6 @@ static int _client_rx_headers_done_cb(h1_codec_request_state_t *hrs, bool has_bo
hreq->request_dlv = qdr_link_deliver(hconn->in_link, hreq->request_msg, 0, false, 0, 0, 0, 0);
qdr_delivery_set_context(hreq->request_dlv, (void*) hreq);
- qdr_delivery_incref(hreq->request_dlv, "referenced by HTTP1 adaptor");
hreq->request_msg = 0;
}
@@ -911,7 +908,6 @@ void qdr_http1_client_core_link_flow(qdr_http1_adaptor_t *adaptor,
hreq->request_dlv = qdr_link_deliver(hconn->in_link, hreq->request_msg, 0, false, 0, 0, 0, 0);
qdr_delivery_set_context(hreq->request_dlv, (void*) hreq);
- qdr_delivery_incref(hreq->request_dlv, "referenced by HTTP1 adaptor");
hreq->request_msg = 0;
}
}
diff --git a/src/adaptors/http1/http1_codec.c b/src/adaptors/http1/http1_codec.c
index 7b63937..e1348d0 100644
--- a/src/adaptors/http1/http1_codec.c
+++ b/src/adaptors/http1/http1_codec.c
@@ -212,6 +212,7 @@ static void h1_codec_request_state_free(h1_codec_request_state_t *hrs)
assert(conn->decoder.hrs != hrs);
assert(conn->encoder.hrs != hrs);
DEQ_REMOVE(conn->hrs_queue, hrs);
+ free(hrs->method);
free_h1_codec_request_state_t(hrs);
}
}
diff --git a/src/adaptors/http1/http1_private.h b/src/adaptors/http1/http1_private.h
index 1e48146..ce10362 100644
--- a/src/adaptors/http1/http1_private.h
+++ b/src/adaptors/http1/http1_private.h
@@ -154,6 +154,7 @@ struct qdr_http1_connection_t {
// State if connected to an HTTP server
struct {
+ qd_timer_t *activate_timer;
qd_timer_t *reconnect_timer;
int reconnect_count;
} server;
diff --git a/src/adaptors/http1/http1_server.c b/src/adaptors/http1/http1_server.c
index 5c056f1..d76f343 100644
--- a/src/adaptors/http1/http1_server.c
+++ b/src/adaptors/http1/http1_server.c
@@ -114,6 +114,7 @@ static void _server_rx_done_cb(h1_codec_request_state_t *hrs);
static void _server_request_complete_cb(h1_codec_request_state_t *hrs, bool cancelled);
static void _handle_connection_events(pn_event_t *e, qd_server_t *qd_server, void *context);
static void _do_reconnect(void *context);
+static void _do_activate(void *context);
static void _server_response_msg_free(_server_request_t *req, _server_response_msg_t *rmsg);
static void _server_request_free(_server_request_t *req);
static void _server_connection_free(qdr_http1_connection_t *hconn);
@@ -150,6 +151,9 @@ static qdr_http1_connection_t *_create_server_connection(qd_http_connector_t *ct
// for initiating a connection to the server
hconn->server.reconnect_timer = qd_timer(qdr_http1_adaptor->core->qd, _do_reconnect, hconn);
+ // to run qdr_connection_process() when there is no raw connection to wake
+ hconn->server.activate_timer = qd_timer(qdr_http1_adaptor->core->qd, _do_activate, hconn);
+
// Create the qdr_connection
qdr_connection_info_t *info = qdr_connection_info(false, //bool is_encrypted,
@@ -212,8 +216,9 @@ qd_http_connector_t *qd_http1_configure_connector(qd_dispatch_t *qd, const qd_ht
qd_log(qdr_http1_adaptor->log, QD_LOG_ERROR, "Unable to create http connector: no memory");
return 0;
}
-
+ c->config = *config;
DEQ_ITEM_INIT(c);
+
qdr_http1_connection_t *hconn = _create_server_connection(c, qd, config);
if (hconn) {
sys_mutex_lock(qdr_http1_adaptor->lock);
@@ -376,6 +381,21 @@ static void _do_reconnect(void *context)
}
+// This adapter attempts to keep the qdr_connection_t open as it tries to
+// re-connect to the server. During this reconnect phase there is no raw
+// connection. If the core needs to process the qdr_connection_t when there is
+// no raw connection to wake this zero-length timer handler will perform the
+// connection processing (under the I/O thread).
+//
+static void _do_activate(void *context)
+{
+ qdr_http1_connection_t *hconn = (qdr_http1_connection_t*) context;
+ if (hconn->qdr_conn) {
+ while (qdr_connection_process(hconn->qdr_conn)) {}
+ }
+}
+
+
// Proton Raw Connection Events
//
static void _handle_connection_events(pn_event_t *e, qd_server_t *qd_server, void *context)
@@ -419,14 +439,12 @@ static void _handle_connection_events(pn_event_t *e, qd_server_t *qd_server, voi
hconn->raw_conn = 0;
_server_connection_free(hconn);
return;
- } else {
- // prevent the core from activating this connection
- // until we can re-establish it
- sys_mutex_lock(qdr_http1_adaptor->lock);
- hconn->raw_conn = 0;
- sys_mutex_unlock(qdr_http1_adaptor->lock);
}
+ sys_mutex_lock(qdr_http1_adaptor->lock);
+ hconn->raw_conn = 0;
+ sys_mutex_unlock(qdr_http1_adaptor->lock);
+
// if the current request was not completed, cancel it. it's ok if
// there are outstanding *response* deliveries in flight as long as the
// response(s) have been completely received from the server
@@ -835,7 +853,6 @@ static int _server_rx_headers_done_cb(h1_codec_request_state_t *hrs, bool has_bo
qd_iterator_reset_view(addr, ITER_VIEW_ADDRESS_HASH);
rmsg->dlv = qdr_link_deliver_to(hconn->in_link, rmsg->msg, 0, addr, false, 0, 0, 0, 0);
qdr_delivery_set_context(rmsg->dlv, (void*) hreq);
- qdr_delivery_incref(rmsg->dlv, "referenced by HTTP1 adaptor");
rmsg->msg = 0; // now owned by delivery
}
@@ -992,17 +1009,15 @@ void qdr_http1_server_core_link_flow(qdr_http1_adaptor_t *adaptor,
qd_iterator_t *addr = qd_message_field_iterator(rmsg->msg, QD_FIELD_TO);
qd_iterator_reset_view(addr, ITER_VIEW_ADDRESS_HASH);
- qdr_delivery_t *dlv = qdr_link_deliver_to(hconn->in_link, rmsg->msg, 0, addr, false, 0, 0, 0, 0);
+ rmsg->dlv = qdr_link_deliver_to(hconn->in_link, rmsg->msg, 0, addr, false, 0, 0, 0, 0);
+ qdr_delivery_set_context(rmsg->dlv, (void*) hreq);
+ rmsg->msg = 0;
if (!rmsg->rx_complete) {
// stop here since response must be complete before we can deliver the next one.
- rmsg->dlv = dlv;
- qdr_delivery_set_context(rmsg->dlv, (void*) hreq);
- qdr_delivery_incref(rmsg->dlv, "referenced by HTTP1 adaptor");
- rmsg->msg = 0;
break;
}
- // the delivery is complete no need to save it
+ // else the delivery is complete no need to save it
_server_response_msg_free(hreq, rmsg);
rmsg = DEQ_HEAD(hreq->responses);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org