diff --git a/include/aws/sdkutils/aws_profile.h b/include/aws/sdkutils/aws_profile.h index d18100e..a45396e 100644 --- a/include/aws/sdkutils/aws_profile.h +++ b/include/aws/sdkutils/aws_profile.h @@ -42,7 +42,22 @@ AWS_EXTERN_C_BEGIN *************************/ /** - * Clean up everything associated with a profile collection + * Increments the reference count on the profile collection, allowing the caller to take a reference to it. + * + * Returns the same profile collection passed in. + */ +AWS_SDKUTILS_API +struct aws_profile_collection *aws_profile_collection_acquire(struct aws_profile_collection *collection); + +/** + * Decrements a profile collection's ref count. When the ref count drops to zero, the collection will be destroyed. + * Returns NULL. + */ +AWS_SDKUTILS_API +struct aws_profile_collection *aws_profile_collection_release(struct aws_profile_collection *collection); + +/** + * @Deprecated This is equivalent to aws_profile_collection_release. */ AWS_SDKUTILS_API void aws_profile_collection_destroy(struct aws_profile_collection *profile_collection); diff --git a/source/aws_profile.c b/source/aws_profile.c index 222efab..f5d792c 100644 --- a/source/aws_profile.c +++ b/source/aws_profile.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,7 @@ struct aws_profile_collection { struct aws_allocator *allocator; enum aws_profile_source_type profile_source; struct aws_hash_table profiles; + struct aws_ref_count ref_count; }; /* @@ -592,12 +594,11 @@ static void s_profile_hash_table_value_destroy(void *value) { */ void aws_profile_collection_destroy(struct aws_profile_collection *profile_collection) { - if (profile_collection == NULL) { - return; - } + aws_profile_collection_release(profile_collection); +} +static void s_aws_profile_collection_destroy_internal(struct aws_profile_collection *profile_collection) { aws_hash_table_clean_up(&profile_collection->profiles); - aws_mem_release(profile_collection->allocator, profile_collection); } @@ -741,6 +742,8 @@ struct aws_profile_collection *aws_profile_collection_new_from_merge( } AWS_ZERO_STRUCT(*merged); + aws_ref_count_init( + &merged->ref_count, merged, (aws_simple_completion_callback *)s_aws_profile_collection_destroy_internal); size_t max_profiles = 0; if (config_profiles != NULL) { @@ -781,7 +784,7 @@ struct aws_profile_collection *aws_profile_collection_new_from_merge( return merged; cleanup: - aws_profile_collection_destroy(merged); + s_aws_profile_collection_destroy_internal(merged); return NULL; } @@ -1198,6 +1201,11 @@ static struct aws_profile_collection *s_aws_profile_collection_new_internal( profile_collection->profile_source = source; profile_collection->allocator = allocator; + aws_ref_count_init( + &profile_collection->ref_count, + profile_collection, + (aws_simple_completion_callback *)s_aws_profile_collection_destroy_internal); + if (aws_hash_table_init( &profile_collection->profiles, allocator, @@ -1238,7 +1246,23 @@ static struct aws_profile_collection *s_aws_profile_collection_new_internal( return profile_collection; cleanup: - aws_profile_collection_destroy(profile_collection); + s_aws_profile_collection_destroy_internal(profile_collection); + + return NULL; +} + +struct aws_profile_collection *aws_profile_collection_acquire(struct aws_profile_collection *collection) { + if (collection != NULL) { + aws_ref_count_acquire(&collection->ref_count); + } + + return collection; +} + +struct aws_profile_collection *aws_profile_collection_release(struct aws_profile_collection *collection) { + if (collection != NULL) { + aws_ref_count_release(&collection->ref_count); + } return NULL; }