Skip to content

Commit 7cf67ce

Browse files
committed
store by value
1 parent 4615933 commit 7cf67ce

File tree

10 files changed

+138
-159
lines changed

10 files changed

+138
-159
lines changed

include/aws/s3/private/s3_checksum_context.h

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ AWS_EXTERN_C_BEGIN
2222
*/
2323
struct aws_s3_upload_request_checksum_context {
2424
struct aws_allocator *allocator;
25-
struct aws_ref_count ref_count;
2625

2726
/* Configuration */
2827
enum aws_s3_checksum_algorithm algorithm;
@@ -37,56 +36,45 @@ struct aws_s3_upload_request_checksum_context {
3736
};
3837

3938
/**
40-
* Create a new upload request checksum context from configuration and buffer parameters.
39+
* Initialize an upload request checksum context from configuration and buffer parameters.
4140
* This function encapsulates all the complex logic for determining buffer state.
42-
* Returns with reference count of 1.
4341
*
42+
* @param context Pointer to the checksum context to initialize
4443
* @param allocator Memory allocator
4544
* @param checksum_config Meta request level checksum configuration (can be NULL)
46-
* @return New checksum context or NULL on error
45+
* @return AWS_OP_SUCCESS or AWS_OP_ERR
4746
*/
4847
AWS_S3_API
49-
struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_context_new(
48+
int aws_s3_upload_request_checksum_context_init(
5049
struct aws_allocator *allocator,
50+
struct aws_s3_upload_request_checksum_context *context,
5151
const struct aws_s3_meta_request_checksum_config_storage *checksum_config);
5252

5353
/**
54-
* Create a new upload request checksum context with an existing checksum value.
54+
* Initialize an upload request checksum context with an existing checksum value.
5555
* This is useful when resuming uploads or when the checksum is pre-calculated.
56-
* Returns with reference count of 1.
5756
*
57+
* @param context Pointer to the checksum context to initialize
5858
* @param allocator Memory allocator
5959
* @param checksum_config Meta request level checksum configuration (can be NULL)
6060
* @param existing_checksum Pre-calculated checksum value as a byte cursor
61-
* @return New checksum context or NULL on error (e.g., if checksum size doesn't match algorithm)
61+
* @return AWS_OP_SUCCESS or AWS_OP_ERR (e.g., if checksum size doesn't match algorithm)
6262
*/
6363
AWS_S3_API
64-
struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_context_new_with_existing_checksum(
64+
int aws_s3_upload_request_checksum_context_init_with_existing_checksum(
6565
struct aws_allocator *allocator,
66+
struct aws_s3_upload_request_checksum_context *context,
6667
const struct aws_s3_meta_request_checksum_config_storage *checksum_config,
6768
struct aws_byte_cursor existing_checksum);
6869

6970
/**
70-
* Acquire a reference to the upload request checksum context.
71-
* Use this when transferring ownership to another function/structure.
71+
* Clean up resources associated with an upload request checksum context.
72+
* This does not free the context itself, just its internal resources.
7273
*
73-
* @param context The checksum context to acquire
74-
* @return The same context pointer (for convenience)
74+
* @param context Pointer to the checksum context to clean up
7575
*/
7676
AWS_S3_API
77-
struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_context_acquire(
78-
struct aws_s3_upload_request_checksum_context *context);
79-
80-
/**
81-
* Release a reference to the upload request checksum context.
82-
* When the reference count reaches zero, the context will be destroyed.
83-
* Always returns NULL.
84-
*
85-
* @param context The checksum context to release
86-
*/
87-
AWS_S3_API
88-
struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_context_release(
89-
struct aws_s3_upload_request_checksum_context *context);
77+
void aws_s3_upload_request_checksum_context_clean_up(struct aws_s3_upload_request_checksum_context *context);
9078

9179
/**
9280
* Check if checksum calculation is needed based on context state.

include/aws/s3/private/s3_meta_request_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <aws/common/task_scheduler.h>
1515
#include <aws/http/request_response.h>
1616

17+
#include "aws/s3/private/s3_checksum_context.h"
1718
#include "aws/s3/private/s3_checksums.h"
1819
#include "aws/s3/private/s3_client_impl.h"
1920
#include "aws/s3/private/s3_request.h"
@@ -25,7 +26,6 @@ struct aws_s3_request;
2526
struct aws_http_headers;
2627
struct aws_http_make_request_options;
2728
struct aws_retry_strategy;
28-
struct aws_s3_upload_request_checksum_context;
2929
enum aws_s3_meta_request_state {
3030
AWS_S3_META_REQUEST_STATE_ACTIVE,
3131
AWS_S3_META_REQUEST_STATE_FINISHED,
@@ -294,7 +294,7 @@ struct aws_s3_meta_request {
294294
struct aws_s3_mpu_part_info {
295295
uint64_t size;
296296
struct aws_string *etag;
297-
struct aws_s3_upload_request_checksum_context *checksum_context;
297+
struct aws_s3_upload_request_checksum_context checksum_context;
298298
bool was_previously_uploaded;
299299
};
300300

source/s3_auto_ranged_put.c

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -154,16 +154,22 @@ static int s_process_part_info_synced(const struct aws_s3_part_info *info, void
154154
}
155155

156156
if ((checksum_cur != NULL) && (checksum_cur->len > 0)) {
157-
/* Create checksum context with pre-calculated checksum */
158-
part->checksum_context = aws_s3_upload_request_checksum_context_new_with_existing_checksum(
159-
auto_ranged_put->base.allocator, &auto_ranged_put->base.checksum_config, *checksum_cur);
157+
/* Initialize checksum context with pre-calculated checksum */
158+
if (aws_s3_upload_request_checksum_context_init_with_existing_checksum(
159+
auto_ranged_put->base.allocator,
160+
&part->checksum_context,
161+
&auto_ranged_put->base.checksum_config,
162+
*checksum_cur)) {
163+
aws_mem_release(meta_request->allocator, part);
164+
return AWS_OP_ERR;
165+
}
160166
} else {
161-
part->checksum_context = aws_s3_upload_request_checksum_context_new(
162-
auto_ranged_put->base.allocator, &auto_ranged_put->base.checksum_config);
163-
}
164-
if (!part->checksum_context) {
165-
aws_mem_release(meta_request->allocator, part);
166-
return AWS_OP_ERR;
167+
/* Initialize checksum context */
168+
if (aws_s3_upload_request_checksum_context_init(
169+
auto_ranged_put->base.allocator, &part->checksum_context, &auto_ranged_put->base.checksum_config)) {
170+
aws_mem_release(meta_request->allocator, part);
171+
return AWS_OP_ERR;
172+
}
167173
}
168174
/* Parts might be out of order or have gaps in them.
169175
* Resize array-list to be long enough to hold this part,
@@ -415,7 +421,7 @@ static void s_s3_meta_request_auto_ranged_put_destroy(struct aws_s3_meta_request
415421
struct aws_s3_mpu_part_info *part;
416422
aws_array_list_get_at(&auto_ranged_put->synced_data.part_list, &part, part_index);
417423
if (part != NULL) {
418-
aws_s3_upload_request_checksum_context_release(part->checksum_context);
424+
aws_s3_upload_request_checksum_context_clean_up(&part->checksum_context);
419425
aws_string_destroy(part->etag);
420426
aws_mem_release(auto_ranged_put->base.allocator, part);
421427
}
@@ -1076,8 +1082,13 @@ static void s_s3_prepare_upload_part_on_read_done(void *user_data) {
10761082
/* Add part to array-list */
10771083
struct aws_s3_mpu_part_info *part =
10781084
aws_mem_calloc(meta_request->allocator, 1, sizeof(struct aws_s3_mpu_part_info));
1079-
part->checksum_context =
1080-
aws_s3_upload_request_checksum_context_new(meta_request->allocator, &meta_request->checksum_config);
1085+
if (aws_s3_upload_request_checksum_context_init(
1086+
meta_request->allocator, &part->checksum_context, &meta_request->checksum_config)) {
1087+
aws_s3_meta_request_unlock_synced_data(meta_request);
1088+
aws_mem_release(meta_request->allocator, part);
1089+
error_code = aws_last_error_or_unknown();
1090+
goto on_done;
1091+
}
10811092
part->size = request->request_body.len;
10821093
aws_array_list_set_at(&auto_ranged_put->synced_data.part_list, &part, request->part_number - 1);
10831094
}
@@ -1098,14 +1109,13 @@ static void s_s3_prepare_upload_part_on_read_done(void *user_data) {
10981109
(void *)meta_request);
10991110
goto on_done;
11001111
}
1101-
struct aws_s3_upload_request_checksum_context *context = previously_uploaded_info->checksum_context;
11021112
/* if previously uploaded part had a checksum, compare it to what we just skipped */
1103-
if (context != NULL && context->checksum_calculated == true &&
1113+
if (previously_uploaded_info->checksum_context.checksum_calculated == true &&
11041114
s_verify_part_matches_checksum(
11051115
meta_request->allocator,
11061116
aws_byte_cursor_from_buf(&request->request_body),
11071117
meta_request->checksum_config.checksum_algorithm,
1108-
aws_byte_cursor_from_buf(&context->base64_checksum))) {
1118+
aws_byte_cursor_from_buf(&previously_uploaded_info->checksum_context.base64_checksum))) {
11091119
error_code = aws_last_error_or_unknown();
11101120
goto on_done;
11111121
}
@@ -1152,9 +1162,9 @@ static void s_s3_prepare_upload_part_finish(struct aws_s3_prepare_upload_part_jo
11521162
aws_s3_meta_request_lock_synced_data(meta_request);
11531163
struct aws_s3_mpu_part_info *part = NULL;
11541164
aws_array_list_get_at(&auto_ranged_put->synced_data.part_list, &part, request->part_number - 1);
1155-
AWS_ASSERT(part != NULL && part->checksum_context != NULL);
1165+
AWS_ASSERT(part != NULL);
11561166
/* Use checksum context if available, otherwise NULL for new parts */
1157-
checksum_context = part->checksum_context;
1167+
checksum_context = &part->checksum_context;
11581168
/* If checksum already calculated, it means either the part being retried or the part resumed from list
11591169
* parts. Keep reusing the old checksum in case of the request body in memory mangled */
11601170
AWS_ASSERT(
@@ -1229,12 +1239,7 @@ static int s_s3_review_multipart_upload(struct aws_s3_request *request) {
12291239

12301240
struct aws_s3_upload_part_review *part_review = &review.part_array[part_index];
12311241
part_review->size = part->size;
1232-
if (part->checksum_context != NULL) {
1233-
part_review->checksum =
1234-
aws_s3_upload_request_checksum_context_get_checksum_cursor(part->checksum_context);
1235-
} else {
1236-
part_review->checksum = (struct aws_byte_cursor){.ptr = NULL, .len = 0};
1237-
}
1242+
part_review->checksum = aws_s3_upload_request_checksum_context_get_checksum_cursor(&part->checksum_context);
12381243
}
12391244
}
12401245

source/s3_checksum_context.c

Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,19 @@
88
#include <aws/common/encoding.h>
99
#include <aws/common/logging.h>
1010

11-
static void s_aws_s3_upload_request_checksum_context_destroy(void *context) {
12-
struct aws_s3_upload_request_checksum_context *checksum_context = context;
13-
aws_byte_buf_clean_up(&checksum_context->base64_checksum);
14-
aws_mem_release(checksum_context->allocator, checksum_context);
15-
}
16-
17-
static struct aws_s3_upload_request_checksum_context *s_s3_upload_request_checksum_context_new_base(
11+
static int s_s3_upload_request_checksum_context_init_base(
1812
struct aws_allocator *allocator,
13+
struct aws_s3_upload_request_checksum_context *context,
1914
const struct aws_s3_meta_request_checksum_config_storage *checksum_config) {
2015
AWS_PRECONDITION(allocator);
16+
AWS_ZERO_STRUCT(*context);
2117

22-
struct aws_s3_upload_request_checksum_context *context =
23-
aws_mem_calloc(allocator, 1, sizeof(struct aws_s3_upload_request_checksum_context));
24-
25-
aws_ref_count_init(&context->ref_count, context, s_aws_s3_upload_request_checksum_context_destroy);
2618
context->allocator = allocator;
2719
/* Handle case where no checksum config is provided */
2820
if (!checksum_config || checksum_config->checksum_algorithm == AWS_SCA_NONE) {
2921
context->algorithm = AWS_SCA_NONE;
3022
context->encoded_checksum_size = 0;
31-
return context;
23+
return AWS_OP_SUCCESS;
3224
}
3325

3426
/* Extract configuration */
@@ -40,65 +32,60 @@ static struct aws_s3_upload_request_checksum_context *s_s3_upload_request_checks
4032
size_t encoded_size = 0;
4133
if (aws_base64_compute_encoded_len(context->encoded_checksum_size, &encoded_size)) {
4234
AWS_LOGF_ERROR(AWS_LS_S3_GENERAL, "Failed to compute base64 encoded length for checksum");
43-
aws_s3_upload_request_checksum_context_release(context);
44-
return NULL;
35+
aws_s3_upload_request_checksum_context_clean_up(context);
36+
return AWS_OP_ERR;
4537
}
4638
context->encoded_checksum_size = encoded_size;
47-
return context;
39+
return AWS_OP_SUCCESS;
4840
}
4941

50-
struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_context_new(
42+
int aws_s3_upload_request_checksum_context_init(
5143
struct aws_allocator *allocator,
44+
struct aws_s3_upload_request_checksum_context *context,
5245
const struct aws_s3_meta_request_checksum_config_storage *checksum_config) {
53-
struct aws_s3_upload_request_checksum_context *context =
54-
s_s3_upload_request_checksum_context_new_base(allocator, checksum_config);
55-
if (context && context->encoded_checksum_size > 0) {
56-
/* Initial the buffer for checksum */
46+
AWS_PRECONDITION(context);
47+
AWS_PRECONDITION(allocator);
48+
if (s_s3_upload_request_checksum_context_init_base(allocator, context, checksum_config) != AWS_OP_SUCCESS) {
49+
return AWS_OP_ERR;
50+
}
51+
if (context->encoded_checksum_size > 0) {
52+
/* Initialize the buffer for checksum */
5753
aws_byte_buf_init(&context->base64_checksum, allocator, context->encoded_checksum_size);
5854
}
59-
return context;
55+
56+
return AWS_OP_SUCCESS;
6057
}
6158

62-
struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_context_new_with_existing_checksum(
59+
int aws_s3_upload_request_checksum_context_init_with_existing_checksum(
6360
struct aws_allocator *allocator,
61+
struct aws_s3_upload_request_checksum_context *context,
6462
const struct aws_s3_meta_request_checksum_config_storage *checksum_config,
6563
struct aws_byte_cursor existing_checksum) {
66-
struct aws_s3_upload_request_checksum_context *context =
67-
s_s3_upload_request_checksum_context_new_base(allocator, checksum_config);
68-
if (context) {
69-
/* Initial the buffer for checksum from the exist checksum */
70-
if (context->encoded_checksum_size != existing_checksum.len) {
71-
struct aws_byte_cursor algo_name = aws_get_checksum_algorithm_name(context->algorithm);
72-
AWS_LOGF_ERROR(
73-
AWS_LS_S3_GENERAL,
74-
"Encoded checksum size mismatch during creating the context for algorithm " PRInSTR
75-
": expected %zu bytes, got %zu bytes",
76-
AWS_BYTE_CURSOR_PRI(algo_name),
77-
context->encoded_checksum_size,
78-
existing_checksum.len);
79-
aws_s3_upload_request_checksum_context_release(context);
80-
return NULL;
81-
}
82-
aws_byte_buf_init_copy_from_cursor(&context->base64_checksum, allocator, existing_checksum);
83-
context->checksum_calculated = true;
64+
AWS_PRECONDITION(context);
65+
AWS_PRECONDITION(allocator);
66+
if (s_s3_upload_request_checksum_context_init_base(allocator, context, checksum_config) != AWS_OP_SUCCESS) {
67+
return AWS_OP_ERR;
8468
}
85-
return context;
86-
}
8769

88-
struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_context_acquire(
89-
struct aws_s3_upload_request_checksum_context *context) {
90-
if (context) {
91-
aws_ref_count_acquire(&context->ref_count);
70+
/* Check for size mismatch */
71+
if (context->encoded_checksum_size != existing_checksum.len) {
72+
struct aws_byte_cursor algo_name = aws_get_checksum_algorithm_name(context->algorithm);
73+
AWS_LOGF_ERROR(
74+
AWS_LS_S3_GENERAL,
75+
"Encoded checksum size mismatch during initializing the context for algorithm " PRInSTR
76+
": expected %zu bytes, got %zu bytes",
77+
AWS_BYTE_CURSOR_PRI(algo_name),
78+
context->encoded_checksum_size,
79+
existing_checksum.len);
80+
aws_s3_upload_request_checksum_context_clean_up(context);
81+
return AWS_OP_ERR;
9282
}
93-
return context;
94-
}
95-
96-
struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_context_release(
97-
struct aws_s3_upload_request_checksum_context *context) {
98-
if (context) {
99-
aws_ref_count_release(&context->ref_count);
83+
if (aws_byte_buf_init_copy_from_cursor(&context->base64_checksum, allocator, existing_checksum)) {
84+
return AWS_OP_ERR;
10085
}
101-
return NULL;
86+
context->checksum_calculated = true;
87+
88+
return AWS_OP_SUCCESS;
10289
}
10390

10491
bool aws_s3_upload_request_checksum_context_should_calculate(
@@ -145,3 +132,11 @@ struct aws_byte_cursor aws_s3_upload_request_checksum_context_get_checksum_curso
145132
}
146133
return aws_byte_cursor_from_buf(&context->base64_checksum);
147134
}
135+
136+
void aws_s3_upload_request_checksum_context_clean_up(struct aws_s3_upload_request_checksum_context *context) {
137+
if (!context) {
138+
return;
139+
}
140+
141+
aws_byte_buf_clean_up(&context->base64_checksum);
142+
}

source/s3_chunk_stream.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ static void s_aws_input_chunk_stream_destroy(struct aws_chunk_stream *impl) {
167167
}
168168
aws_byte_buf_clean_up(&impl->pre_chunk_buffer);
169169
aws_byte_buf_clean_up(&impl->post_chunk_buffer);
170-
aws_s3_upload_request_checksum_context_release(impl->checksum_context);
171170
aws_mem_release(impl->allocator, impl);
172171
}
173172
}
@@ -196,7 +195,7 @@ struct aws_input_stream *aws_chunk_stream_new(
196195
enum aws_s3_checksum_algorithm algorithm = AWS_SCA_NONE;
197196
struct aws_byte_buf *checksum_buffer = NULL;
198197

199-
impl->checksum_context = aws_s3_upload_request_checksum_context_acquire(checksum_context);
198+
impl->checksum_context = checksum_context;
200199

201200
algorithm = checksum_context->algorithm;
202201
checksum_buffer = &checksum_context->base64_checksum;

source/s3_copy_object.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ static void s_s3_meta_request_copy_object_destroy(struct aws_s3_meta_request *me
125125
struct aws_s3_mpu_part_info *part = NULL;
126126
aws_array_list_get_at(&copy_object->synced_data.part_list, &part, part_index);
127127
aws_string_destroy(part->etag);
128-
aws_s3_upload_request_checksum_context_release(part->checksum_context);
128+
aws_s3_upload_request_checksum_context_clean_up(&part->checksum_context);
129129
aws_mem_release(meta_request->allocator, part);
130130
}
131131

source/s3_default_meta_request.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,13 +354,15 @@ static void s_s3_default_prepare_request_finish(
354354
/* Only PUT Object and Upload part support trailing checksum, that needs the special encoding even if the body
355355
* has 0 length. */
356356
/* Create checksum context from config if needed */
357-
struct aws_s3_upload_request_checksum_context *checksum_context =
358-
aws_s3_upload_request_checksum_context_new(meta_request->allocator, &meta_request->checksum_config);
357+
struct aws_s3_upload_request_checksum_context checksum_context;
359358

360-
aws_s3_message_util_assign_body(meta_request->allocator, &request->request_body, message, checksum_context);
359+
aws_s3_upload_request_checksum_context_init(
360+
meta_request->allocator, &checksum_context, &meta_request->checksum_config);
361+
362+
aws_s3_message_util_assign_body(meta_request->allocator, &request->request_body, message, &checksum_context);
361363

362364
/* Release the context reference */
363-
aws_s3_upload_request_checksum_context_release(checksum_context);
365+
aws_s3_upload_request_checksum_context_clean_up(&checksum_context);
364366
}
365367
aws_s3_request_setup_send_data(request, message);
366368

0 commit comments

Comments
 (0)