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