You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gm...@apache.org on 2016/03/01 18:28:24 UTC
[2/3] qpid-dispatch git commit: DISPATCH-179 - Fixed memory leak of
qd_composed_field_t and qd_field_iterator_t objects when doing c management
agent requests
DISPATCH-179 - Fixed memory leak of qd_composed_field_t and qd_field_iterator_t objects when doing c management agent requests
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/f305dbf5
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/f305dbf5
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/f305dbf5
Branch: refs/heads/tross-DISPATCH-179-1-QDMESSAGE-MEMLEAK
Commit: f305dbf5613a708216c63066ccc249f1c982d33f
Parents: 2437acf
Author: Ganesh Murthy <gm...@redhat.com>
Authored: Mon Feb 29 10:04:04 2016 -0500
Committer: Ganesh Murthy <gm...@redhat.com>
Committed: Mon Feb 29 10:04:04 2016 -0500
----------------------------------------------------------------------
src/router_core/agent.c | 58 +++++++++++++----------
src/router_core/management_agent.c | 76 +++++++++++++++++-------------
src/router_core/router_core_private.h | 1 -
3 files changed, 75 insertions(+), 60 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f305dbf5/src/router_core/agent.c
----------------------------------------------------------------------
diff --git a/src/router_core/agent.c b/src/router_core/agent.c
index b5b9fc6..c45e20e 100644
--- a/src/router_core/agent.c
+++ b/src/router_core/agent.c
@@ -50,9 +50,7 @@ static void qdr_agent_response_handler(void *context)
if (query) {
core->agent_response_handler(query->context, query->status, query->more);
if (!query->more) {
- if (query->next_key)
- qdr_field_free(query->next_key);
- free_qdr_query_t(query);
+ qdr_query_free(query);
}
}
}
@@ -73,7 +71,6 @@ void qdr_agent_enqueue_response_CT(qdr_core_t *core, qdr_query_t *query)
qdr_query_t *qdr_query(qdr_core_t *core,
void *context,
qd_router_entity_type_t type,
- qd_parsed_field_t *attribute_names,
qd_composed_field_t *body)
{
qdr_query_t *query = new_qdr_query_t();
@@ -110,7 +107,7 @@ void qdr_manage_create(qdr_core_t *core,
qdr_action_t *action = qdr_action(qdr_manage_create_CT, "manage_create");
// Create a query object here
- action->args.agent.query = qdr_query(core, context, type, 0, out_body);
+ action->args.agent.query = qdr_query(core, context, type, out_body);
action->args.agent.name = name;
action->args.agent.in_body = in_body;
@@ -126,7 +123,7 @@ void qdr_manage_delete(qdr_core_t *core, void *context,
qdr_action_t *action = qdr_action(qdr_manage_delete_CT, "manage_delete");
// Create a query object here
- action->args.agent.query = qdr_query(core, context, type, 0, 0);
+ action->args.agent.query = qdr_query(core, context, type, 0);
action->args.agent.name = name;
action->args.agent.identity = identity;
@@ -143,7 +140,7 @@ void qdr_manage_read(qdr_core_t *core, void *context,
qdr_action_t *action = qdr_action(qdr_manage_read_CT, "manage_read");
// Create a query object here
- action->args.agent.query = qdr_query(core, context, entity_type, 0, body);
+ action->args.agent.query = qdr_query(core, context, entity_type, body);
action->args.agent.identity = identity;
action->args.agent.name = name;
@@ -170,32 +167,32 @@ qdr_query_t *qdr_manage_query(qdr_core_t *core,
qd_composed_field_t *body)
{
- qdr_query_t* query = qdr_query(core, context, type, attribute_names, body);
+ qdr_query_t* query = qdr_query(core, context, type, body);
switch (query->entity_type) {
- case QD_ROUTER_PROVISIONED:
- qdr_agent_set_columns(query, attribute_names, qdr_provisioned_columns, QDR_PROVISIONED_COLUMN_COUNT);
- break;
+ case QD_ROUTER_PROVISIONED:
+ qdr_agent_set_columns(query, attribute_names, qdr_provisioned_columns, QDR_PROVISIONED_COLUMN_COUNT);
+ break;
- case QD_ROUTER_CONNECTION:
- break;
+ case QD_ROUTER_CONNECTION:
+ break;
- case QD_ROUTER_LINK:
- qdr_agent_set_columns(query, attribute_names, qdr_link_columns, QDR_LINK_COLUMN_COUNT);
- break;
+ case QD_ROUTER_LINK:
+ qdr_agent_set_columns(query, attribute_names, qdr_link_columns, QDR_LINK_COLUMN_COUNT);
+ break;
- case QD_ROUTER_ADDRESS:
- qdr_agent_set_columns(query, attribute_names, qdr_address_columns, QDR_ADDRESS_COLUMN_COUNT);
- break;
+ case QD_ROUTER_ADDRESS:
+ qdr_agent_set_columns(query, attribute_names, qdr_address_columns, QDR_ADDRESS_COLUMN_COUNT);
+ break;
- case QD_ROUTER_WAYPOINT:
- break;
+ case QD_ROUTER_WAYPOINT:
+ break;
- case QD_ROUTER_EXCHANGE:
- break;
+ case QD_ROUTER_EXCHANGE:
+ break;
- case QD_ROUTER_BINDING:
- break;
+ case QD_ROUTER_BINDING:
+ break;
}
return query;
@@ -234,6 +231,17 @@ void qdr_query_get_next(qdr_query_t *query)
void qdr_query_free(qdr_query_t *query)
{
+ if(!query)
+ return;
+
+ if (query->next_key)
+ qdr_field_free(query->next_key);
+
+ if(query->body)
+ qd_compose_free(query->body);
+
+ free_qdr_query_t(query);
+
}
static void qdr_agent_emit_columns(qdr_query_t *query, const char *qdr_columns[], int column_count)
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f305dbf5/src/router_core/management_agent.c
----------------------------------------------------------------------
diff --git a/src/router_core/management_agent.c b/src/router_core/management_agent.c
index 7bd0b9a..1735dd2 100644
--- a/src/router_core/management_agent.c
+++ b/src/router_core/management_agent.c
@@ -28,16 +28,16 @@
#include "dispatch_private.h"
#include "alloc.h"
-const char *entity_type_key = "entityType";
-const char *type_key = "type";
-const char *count_key = "count";
-const char *offset_key = "offset";
-const char *name_key = "name";
-const char *identity_key = "identity";
+const char *ENTITY = "entityType";
+const char *TYPE = "type";
+const char *COUNT = "count";
+const char *OFFSET = "offset";
+const char *NAME = "name";
+const char *IDENTITY = "identity";
-const char *operation_type_key = "operation";
-const char *attribute_names_key = "attributeNames";
+const char *OPERATION = "operation";
+const char *ATTRIBUTE_NAMES = "attributeNames";
const unsigned char *provisioned_entity_type = (unsigned char*) "org.apache.qpid.dispatch.router.provisioned";
const unsigned char *waypoint_entity_type = (unsigned char*) "org.apache.qpid.dispatch.waypoint";
@@ -144,7 +144,7 @@ static void qd_set_properties(qd_message_t *msg,
qd_compose_insert_null(*fld);
qd_compose_insert_typed_iterator(*fld, correlation_id);
qd_compose_end_list(*fld);
-
+ qd_field_iterator_free(correlation_id);
}
@@ -193,6 +193,9 @@ static void qd_manage_response_handler(void *context, const qd_amqp_error_t *sta
// ctx->query has also been already freed
// Just go over this with Ted to see if I freed everything.
+ qd_field_iterator_free(reply_to);
+ qd_compose_free(fld);
+
if (ctx->msg)
qd_message_free(ctx->msg);
if(ctx->source)
@@ -210,23 +213,28 @@ static void qd_core_agent_query_handler(qdr_core_t *core,
int *offset)
{
//
- // Add the Body
+ // Add the Body. This body field is freed by qdr_query_free()
//
qd_composed_field_t *field = qd_compose(QD_PERFORMATIVE_BODY_AMQP_VALUE, 0);
// Start a map in the body. Look for the end map in the callback function, qd_manage_response_handler.
qd_compose_start_map(field);
- qd_compose_insert_string(field, attribute_names_key); //add a "attributeNames" key
+ //add a "attributeNames" key
+ qd_compose_insert_string(field, ATTRIBUTE_NAMES);
- // Call local function that creates and returns a qd_management_context_t containing the values passed in.
+ // Call local function that creates and returns a local qd_management_context_t object containing the values passed in.
qd_management_context_t *ctx = qd_management_context(qd_message(), msg, field, 0, core, operation_type, (*count));
// Grab the attribute names from the incoming message body. The attribute names will be used later on in the response.
qd_parsed_field_t *attribute_names_parsed_field = 0;
- qd_parsed_field_t *body = qd_parse(qd_message_field_iterator(msg, QD_FIELD_BODY));
- if (body != 0 && qd_parse_is_map(body))
- attribute_names_parsed_field = qd_parse_value_by_key(body, attribute_names_key);
+
+ qd_field_iterator_t *body_iter = qd_message_field_iterator(msg, QD_FIELD_BODY);
+
+ qd_parsed_field_t *body = qd_parse(body_iter);
+ if (body != 0 && qd_parse_is_map(body)) {
+ attribute_names_parsed_field = qd_parse_value_by_key(body, ATTRIBUTE_NAMES);
+ }
// Set the callback function.
qdr_manage_handler(core, qd_manage_response_handler);
@@ -238,6 +246,9 @@ static void qd_core_agent_query_handler(qdr_core_t *core,
qd_compose_start_list(field); //start the list for results
qdr_query_get_first(ctx->query, (*offset));
+
+ qd_field_iterator_free(body_iter);
+ qd_parse_free(body);
}
@@ -314,9 +325,10 @@ static void qd_core_agent_delete_handler(qdr_core_t *core,
/**
- * Checks the content of the message to see if this can be handled by this agent.
+ * Checks the content of the message to see if this can be handled by the C-management agent. If this agent cannot handle it, it will be
+ * forwarded to the Python agent.
*/
-static bool qd_can_handle_request(qd_field_iterator_t *props,
+static bool qd_can_handle_request(qd_parsed_field_t *properties_fld,
qd_router_entity_type_t *entity_type,
qd_router_operation_type_t *operation_type,
qd_field_iterator_t **identity_iter,
@@ -324,11 +336,9 @@ static bool qd_can_handle_request(qd_field_iterator_t *props,
int *count,
int *offset)
{
- qd_parsed_field_t *fld = qd_parse(props);
-
// The must be a property field and that property field should be a AMQP map. This is true for QUERY but I need
// to check if it true for CREATE, UPDATE and DELETE
- if (fld == 0 || !qd_parse_is_map(fld))
+ if (properties_fld == 0 || !qd_parse_is_map(properties_fld))
return false;
//
@@ -337,25 +347,24 @@ static bool qd_can_handle_request(qd_field_iterator_t *props,
// 'entityType': 'org.apache.qpid.dispatch.router.link'
// TODO - Add more entity types here. The above is not a complete list.
- qd_parsed_field_t *parsed_field = qd_parse_value_by_key(fld, identity_key);
+ qd_parsed_field_t *parsed_field = qd_parse_value_by_key(properties_fld, IDENTITY);
if (parsed_field!=0) {
*identity_iter = qd_parse_raw(parsed_field);
}
- parsed_field = qd_parse_value_by_key(fld, name_key);
+ parsed_field = qd_parse_value_by_key(properties_fld, NAME);
if (parsed_field!=0) {
*name_iter = qd_parse_raw(parsed_field);
}
-
- parsed_field = qd_parse_value_by_key(fld, entity_type_key);
+ parsed_field = qd_parse_value_by_key(properties_fld, ENTITY);
if (parsed_field == 0) { // Sometimes there is no 'entityType' but 'type' might be available.
- parsed_field = qd_parse_value_by_key(fld, type_key);
+ parsed_field = qd_parse_value_by_key(properties_fld, TYPE);
if (parsed_field == 0)
return false;
}
- if (qd_field_iterator_equal(qd_parse_raw(parsed_field), address_entity_type))
+ if (qd_field_iterator_equal(qd_parse_raw(parsed_field), address_entity_type))
*entity_type = QD_ROUTER_ADDRESS;
else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), link_entity_type))
*entity_type = QD_ROUTER_LINK;
@@ -367,7 +376,7 @@ static bool qd_can_handle_request(qd_field_iterator_t *props,
return false;
- parsed_field = qd_parse_value_by_key(fld, operation_type_key);
+ parsed_field = qd_parse_value_by_key(properties_fld, OPERATION);
if (parsed_field == 0)
return false;
@@ -387,20 +396,18 @@ static bool qd_can_handle_request(qd_field_iterator_t *props,
return false;
// Obtain the count and offset.
- parsed_field = qd_parse_value_by_key(fld, count_key);
+ parsed_field = qd_parse_value_by_key(properties_fld, COUNT);
if (parsed_field)
(*count) = qd_parse_as_int(parsed_field);
else
(*count) = -1;
- parsed_field = qd_parse_value_by_key(fld, offset_key);
+ parsed_field = qd_parse_value_by_key(properties_fld, OFFSET);
if (parsed_field)
(*offset) = qd_parse_as_int(parsed_field);
else
(*offset) = 0;
- qd_parse_free(parsed_field);
-
return true;
}
@@ -424,7 +431,9 @@ void qdr_management_agent_on_message(void *context, qd_message_t *msg, int unuse
int32_t count = 0;
int32_t offset = 0;
- if (qd_can_handle_request(app_properties_iter, &entity_type, &operation_type, &identity_iter, &name_iter, &count, &offset)) {
+ qd_parsed_field_t *properties_fld = qd_parse(app_properties_iter);
+
+ if (qd_can_handle_request(properties_fld, &entity_type, &operation_type, &identity_iter, &name_iter, &count, &offset)) {
switch (operation_type) {
case QD_ROUTER_OPERATION_QUERY:
qd_core_agent_query_handler(core, entity_type, operation_type, msg, &count, &offset);
@@ -450,8 +459,7 @@ void qdr_management_agent_on_message(void *context, qd_message_t *msg, int unuse
}
qd_field_iterator_free(app_properties_iter);
- qd_field_iterator_free(name_iter);
- qd_field_iterator_free(identity_iter);
+ qd_parse_free(properties_fld);
}
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/f305dbf5/src/router_core/router_core_private.h
----------------------------------------------------------------------
diff --git a/src/router_core/router_core_private.h b/src/router_core/router_core_private.h
index e8d1508..60a9ed0 100644
--- a/src/router_core/router_core_private.h
+++ b/src/router_core/router_core_private.h
@@ -531,6 +531,5 @@ void qdr_connection_activate_CT(qdr_core_t *core, qdr_connection_t *conn);
qdr_query_t *qdr_query(qdr_core_t *core,
void *context,
qd_router_entity_type_t type,
- qd_parsed_field_t *attribute_names,
qd_composed_field_t *body);
#endif
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org