A small memory footprint AMQP implimentation
Dependents: iothub_client_sample_amqp remote_monitoring simplesample_amqp
Diff: link.c
- Revision:
- 21:f9c433d8e6ca
- Parent:
- 20:206846c14c80
- Child:
- 23:1111ee8bcba4
diff -r 206846c14c80 -r f9c433d8e6ca link.c --- 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;