A small memory footprint AMQP implimentation

Dependents:   iothub_client_sample_amqp remote_monitoring simplesample_amqp

Revision:
21:f9c433d8e6ca
Parent:
20:206846c14c80
Child:
23:1111ee8bcba4
--- a/link.c	Fri Mar 10 11:47:49 2017 -0800
+++ b/link.c	Fri Mar 24 16:35:45 2017 -0700
@@ -5,11 +5,11 @@
 #include <string.h>
 #include <stdint.h>
 #include <stdbool.h>
+#include "azure_c_shared_utility/gballoc.h"
 #include "azure_uamqp_c/link.h"
 #include "azure_uamqp_c/session.h"
 #include "azure_uamqp_c/amqpvalue.h"
 #include "azure_uamqp_c/amqp_definitions.h"
-#include "azure_uamqp_c/amqpalloc.h"
 #include "azure_uamqp_c/amqp_frame_codec.h"
 #include "azure_c_shared_utility/optimize_size.h"
 #include "azure_c_shared_utility/xlogging.h"
@@ -67,6 +67,32 @@
 	}
 }
 
+static void remove_all_pending_deliveries(LINK_INSTANCE* link, bool indicate_settled)
+{
+    if (link->pending_deliveries != NULL)
+    {
+        LIST_ITEM_HANDLE item = singlylinkedlist_get_head_item(link->pending_deliveries);
+        while (item != NULL)
+        {
+            LIST_ITEM_HANDLE next_item = singlylinkedlist_get_next_item(item);
+            DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)singlylinkedlist_item_get_value(item);
+            if (delivery_instance != NULL)
+            {
+                if (indicate_settled && (delivery_instance->on_delivery_settled != NULL))
+                {
+                    delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, NULL);
+                }
+                free(delivery_instance);
+            }
+
+            item = next_item;
+        }
+
+        singlylinkedlist_destroy(link->pending_deliveries);
+        link->pending_deliveries = NULL;
+    }
+}
+
 static int send_flow(LINK_INSTANCE* link)
 {
 	int result;
@@ -446,7 +472,7 @@
                                 else
                                 {
                                     delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, delivery_state);
-                                    amqpalloc_free(delivery_instance);
+                                    free(delivery_instance);
                                     if (singlylinkedlist_remove(link_instance->pending_deliveries, pending_delivery) != 0)
                                     {
                                         /* error */
@@ -533,10 +559,12 @@
 	}
 	else if (new_session_state == SESSION_STATE_DISCARDING)
 	{
+        remove_all_pending_deliveries(link_instance, true);
 		set_link_state(link_instance, LINK_STATE_DETACHED);
 	}
 	else if (new_session_state == SESSION_STATE_ERROR)
 	{
+        remove_all_pending_deliveries(link_instance, true);
 		set_link_state(link_instance, LINK_STATE_ERROR);
 	}
 }
@@ -559,14 +587,14 @@
 	if (link_instance->snd_settle_mode == sender_settle_mode_settled)
 	{
 		delivery_instance->on_delivery_settled(delivery_instance->callback_context, delivery_instance->delivery_id, NULL);
-		amqpalloc_free(delivery_instance);
+		free(delivery_instance);
 		(void)singlylinkedlist_remove(link_instance->pending_deliveries, delivery_instance_list_item);
 	}
 }
 
 LINK_HANDLE link_create(SESSION_HANDLE session, const char* name, role role, AMQP_VALUE source, AMQP_VALUE target)
 {
-	LINK_INSTANCE* result = amqpalloc_malloc(sizeof(LINK_INSTANCE));
+	LINK_INSTANCE* result = malloc(sizeof(LINK_INSTANCE));
 	if (result != NULL)
 	{
 		result->link_state = LINK_STATE_DETACHED;
@@ -591,16 +619,16 @@
 		result->pending_deliveries = singlylinkedlist_create();
 		if (result->pending_deliveries == NULL)
 		{
-			amqpalloc_free(result);
+			free(result);
 			result = NULL;
 		}
 		else
 		{
-			result->name = amqpalloc_malloc(strlen(name) + 1);
+			result->name = malloc(strlen(name) + 1);
 			if (result->name == NULL)
 			{
 				singlylinkedlist_destroy(result->pending_deliveries);
-				amqpalloc_free(result);
+				free(result);
 				result = NULL;
 			}
 			else
@@ -614,8 +642,8 @@
 				if (result->link_endpoint == NULL)
 				{
 					singlylinkedlist_destroy(result->pending_deliveries);
-					amqpalloc_free(result->name);
-					amqpalloc_free(result);
+					free(result->name);
+					free(result);
 					result = NULL;
 				}
 			}
@@ -627,7 +655,7 @@
 
 LINK_HANDLE link_create_from_endpoint(SESSION_HANDLE session, LINK_ENDPOINT_HANDLE link_endpoint, const char* name, role role, AMQP_VALUE source, AMQP_VALUE target)
 {
-	LINK_INSTANCE* result = amqpalloc_malloc(sizeof(LINK_INSTANCE));
+	LINK_INSTANCE* result = malloc(sizeof(LINK_INSTANCE));
 	if (result != NULL)
 	{
 		result->link_state = LINK_STATE_DETACHED;
@@ -659,16 +687,16 @@
 		result->pending_deliveries = singlylinkedlist_create();
 		if (result->pending_deliveries == NULL)
 		{
-			amqpalloc_free(result);
+			free(result);
 			result = NULL;
 		}
 		else
 		{
-			result->name = amqpalloc_malloc(strlen(name) + 1);
+			result->name = malloc(strlen(name) + 1);
 			if (result->name == NULL)
 			{
 				singlylinkedlist_destroy(result->pending_deliveries);
-				amqpalloc_free(result);
+				free(result);
 				result = NULL;
 			}
 			else
@@ -688,32 +716,17 @@
 {
 	if (link != NULL)
 	{
+        remove_all_pending_deliveries((LINK_INSTANCE*)link, false);
+
         link->on_link_state_changed = NULL;
         (void)link_detach(link, true);
         session_destroy_link_endpoint(link->link_endpoint);
 		amqpvalue_destroy(link->source);
 		amqpvalue_destroy(link->target);
-		if (link->pending_deliveries != NULL)
-		{
-			LIST_ITEM_HANDLE item = singlylinkedlist_get_head_item(link->pending_deliveries);
-			while (item != NULL)
-			{
-				LIST_ITEM_HANDLE next_item = singlylinkedlist_get_next_item(item);
-				DELIVERY_INSTANCE* delivery_instance = (DELIVERY_INSTANCE*)singlylinkedlist_item_get_value(item);
-				if (delivery_instance != NULL)
-				{
-					amqpalloc_free(delivery_instance);
-				}
-
-				item = next_item;
-			}
-
-			singlylinkedlist_destroy(link->pending_deliveries);
-		}
 
 		if (link->name != NULL)
 		{
-			amqpalloc_free(link->name);
+			free(link->name);
 		}
 
 		if (link->attach_properties != NULL)
@@ -726,7 +739,7 @@
             free(link->received_payload);
         }
 
-		amqpalloc_free(link);
+		free(link);
 	}
 }
 
@@ -1061,7 +1074,7 @@
 					}
 					else
 					{
-						DELIVERY_INSTANCE* pending_delivery = amqpalloc_malloc(sizeof(DELIVERY_INSTANCE));
+						DELIVERY_INSTANCE* pending_delivery = malloc(sizeof(DELIVERY_INSTANCE));
 						if (pending_delivery == NULL)
 						{
 							result = LINK_TRANSFER_ERROR;
@@ -1076,7 +1089,7 @@
 
 							if (delivery_instance_list_item == NULL)
 							{
-								amqpalloc_free(pending_delivery);
+								free(pending_delivery);
 								result = LINK_TRANSFER_ERROR;
 							}
 							else
@@ -1087,14 +1100,14 @@
 								default:
 								case SESSION_SEND_TRANSFER_ERROR:
 									singlylinkedlist_remove(link->pending_deliveries, delivery_instance_list_item);
-									amqpalloc_free(pending_delivery);
+									free(pending_delivery);
 									result = LINK_TRANSFER_ERROR;
 									break;
 
 								case SESSION_SEND_TRANSFER_BUSY:
 									/* Ensure we remove from list again since sender will attempt to transfer again on flow on */
 									singlylinkedlist_remove(link->pending_deliveries, delivery_instance_list_item);
-									amqpalloc_free(pending_delivery);
+									free(pending_delivery);
 									result = LINK_TRANSFER_BUSY;
 									break;