Skip to content

Commit b76ebf2

Browse files
authored
refcount input stream (#342)
Refcount the input stream and adapt the new api change
1 parent 4333519 commit b76ebf2

File tree

13 files changed

+122
-105
lines changed

13 files changed

+122
-105
lines changed

bin/elasticurl/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ int main(int argc, char **argv) {
763763
}
764764

765765
if (app_ctx.input_body) {
766-
aws_input_stream_destroy(app_ctx.input_body);
766+
aws_input_stream_release(app_ctx.input_body);
767767
}
768768

769769
if (app_ctx.input_file) {

builder.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
{ "name": "aws-c-compression" }
1212
],
1313
"downstream": [
14-
{ "name": "aws-c-auth" }
14+
{ "name": "aws-c-auth" },
15+
{ "name": "aws-c-mqtt" }
1516
],
1617
"test_steps": [
1718
["bash", "./.builder/action/aws-c-http-test.sh"],

codebuild/linux-integration-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ phases:
1010
pre_build:
1111
commands:
1212
- export CC=gcc-7
13-
- export BUILDER_VERSION=v0.8.27
13+
- export BUILDER_VERSION=v0.9.12
1414
- export BUILDER_SOURCE=releases
1515
- export BUILDER_HOST=https://d19elf31gohf1l.cloudfront.net
1616
build:

source/h1_encoder.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ int aws_h1_encoder_message_init_from_request(
256256

257257
AWS_ZERO_STRUCT(*message);
258258

259-
message->body = aws_http_message_get_body_stream(request);
259+
message->body = aws_input_stream_acquire(aws_http_message_get_body_stream(request));
260260
message->pending_chunk_list = pending_chunk_list;
261261

262262
struct aws_byte_cursor method;
@@ -352,7 +352,7 @@ int aws_h1_encoder_message_init_from_response(
352352

353353
AWS_ZERO_STRUCT(*message);
354354

355-
message->body = aws_http_message_get_body_stream(response);
355+
message->body = aws_input_stream_acquire(aws_http_message_get_body_stream(response));
356356
message->pending_chunk_list = pending_chunk_list;
357357

358358
struct aws_byte_cursor version = aws_http_version_to_str(AWS_HTTP_VERSION_1_1);
@@ -432,6 +432,7 @@ int aws_h1_encoder_message_init_from_response(
432432
}
433433

434434
void aws_h1_encoder_message_clean_up(struct aws_h1_encoder_message *message) {
435+
aws_input_stream_release(message->body);
435436
aws_byte_buf_clean_up(&message->outgoing_head_buf);
436437
aws_h1_trailer_destroy(message->trailer);
437438
AWS_ZERO_STRUCT(*message);
@@ -547,18 +548,18 @@ struct aws_h1_chunk *aws_h1_chunk_new(struct aws_allocator *allocator, const str
547548
}
548549

549550
chunk->allocator = allocator;
550-
chunk->data = options->chunk_data;
551+
chunk->data = aws_input_stream_acquire(options->chunk_data);
551552
chunk->data_size = options->chunk_data_size;
552553
chunk->on_complete = options->on_complete;
553554
chunk->user_data = options->user_data;
554555
chunk->chunk_line = aws_byte_buf_from_empty_array(chunk_line_storage, chunk_line_size);
555556
s_populate_chunk_line_buffer(&chunk->chunk_line, options);
556-
557557
return chunk;
558558
}
559559

560560
void aws_h1_chunk_destroy(struct aws_h1_chunk *chunk) {
561561
AWS_PRECONDITION(chunk);
562+
aws_input_stream_release(chunk->data);
562563
aws_mem_release(chunk->allocator, chunk);
563564
}
564565

source/request_response.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ struct aws_http_message *aws_http_message_release(struct aws_http_message *messa
552552
}
553553

554554
aws_http_headers_release(message->headers);
555-
555+
aws_input_stream_release(message->body_stream);
556556
aws_mem_release(message->allocator, message);
557557
} else {
558558
AWS_ASSERT(prev_refcount != 0);
@@ -727,7 +727,13 @@ int aws_http_message_set_response_status(struct aws_http_message *response_messa
727727

728728
void aws_http_message_set_body_stream(struct aws_http_message *message, struct aws_input_stream *body_stream) {
729729
AWS_PRECONDITION(message);
730+
/* release previous stream, if any */
731+
aws_input_stream_release(message->body_stream);
732+
730733
message->body_stream = body_stream;
734+
if (message->body_stream) {
735+
aws_input_stream_acquire(message->body_stream);
736+
}
731737
}
732738

733739
int aws_http1_stream_write_chunk(struct aws_http_stream *http1_stream, const struct aws_http1_chunk_options *options) {

tests/fuzz/fuzz_h2_decoder_correct.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ static struct aws_http_headers *s_generate_headers(
4242
struct aws_http_header path = {.name = aws_http_header_path, .value = aws_byte_cursor_from_c_str("/")};
4343
aws_http_headers_add_header(headers, &path);
4444

45-
struct aws_http_header authority = {.name = aws_http_header_authority,
46-
.value = aws_byte_cursor_from_c_str("example.com")};
45+
struct aws_http_header authority = {
46+
.name = aws_http_header_authority,
47+
.value = aws_byte_cursor_from_c_str("example.com"),
48+
};
4749
aws_http_headers_add_header(headers, &authority);
4850

4951
} else if (header_style == HEADER_STYLE_RESPONSE) {
@@ -252,7 +254,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
252254
struct aws_stream_status body_status;
253255
aws_input_stream_get_status(body, &body_status);
254256
AWS_FATAL_ASSERT(body_complete == body_status.is_end_of_stream)
255-
aws_input_stream_destroy(body);
257+
aws_input_stream_release(body);
256258
break;
257259
}
258260
case AWS_H2_FRAME_T_HEADERS: {

tests/h2_test_helper.c

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ int h2_fake_peer_send_data_frame_with_padding_length(
611611
ASSERT_TRUE(msg->message_data.len != 0);
612612

613613
ASSERT_SUCCESS(testing_channel_push_read_message(peer->testing_channel, msg));
614-
aws_input_stream_destroy(body_stream);
614+
aws_input_stream_release(body_stream);
615615
return AWS_OP_SUCCESS;
616616
}
617617

@@ -643,6 +643,8 @@ int h2_fake_peer_send_connection_preface_default_settings(struct h2_fake_peer *p
643643
/******************************************************************************/
644644

645645
struct aws_input_stream_tester {
646+
struct aws_input_stream base;
647+
struct aws_allocator *allocator;
646648
/* aws_input_stream_byte_cursor provides our actual functionality */
647649
struct aws_input_stream *cursor_stream;
648650

@@ -655,12 +657,12 @@ static int s_aws_input_stream_tester_seek(
655657
int64_t offset,
656658
enum aws_stream_seek_basis basis) {
657659

658-
struct aws_input_stream_tester *impl = stream->impl;
660+
struct aws_input_stream_tester *impl = AWS_CONTAINER_OF(stream, struct aws_input_stream_tester, base);
659661
return aws_input_stream_seek(impl->cursor_stream, offset, basis);
660662
}
661663

662664
static int s_aws_input_stream_tester_read(struct aws_input_stream *stream, struct aws_byte_buf *dest) {
663-
struct aws_input_stream_tester *impl = stream->impl;
665+
struct aws_input_stream_tester *impl = AWS_CONTAINER_OF(stream, struct aws_input_stream_tester, base);
664666

665667
if (impl->is_reading_broken) {
666668
return aws_raise_error(AWS_IO_STREAM_READ_FAILED);
@@ -678,60 +680,49 @@ static int s_aws_input_stream_tester_read(struct aws_input_stream *stream, struc
678680
}
679681

680682
static int s_aws_input_stream_tester_get_status(struct aws_input_stream *stream, struct aws_stream_status *status) {
681-
struct aws_input_stream_tester *impl = stream->impl;
683+
struct aws_input_stream_tester *impl = AWS_CONTAINER_OF(stream, struct aws_input_stream_tester, base);
682684
return aws_input_stream_get_status(impl->cursor_stream, status);
683685
}
684686

685687
static int s_aws_input_stream_tester_get_length(struct aws_input_stream *stream, int64_t *out_length) {
686-
struct aws_input_stream_tester *impl = stream->impl;
688+
struct aws_input_stream_tester *impl = AWS_CONTAINER_OF(stream, struct aws_input_stream_tester, base);
687689
return aws_input_stream_get_length(impl->cursor_stream, out_length);
688690
}
689691

690-
static void s_aws_input_stream_tester_destroy(struct aws_input_stream *stream) {
691-
if (stream) {
692-
struct aws_input_stream_tester *impl = stream->impl;
693-
aws_input_stream_destroy(impl->cursor_stream);
694-
aws_mem_release(stream->allocator, stream);
695-
}
692+
static void s_aws_input_stream_tester_destroy(struct aws_input_stream_tester *impl) {
693+
aws_input_stream_release(impl->cursor_stream);
694+
aws_mem_release(impl->allocator, impl);
696695
}
697696

698697
static struct aws_input_stream_vtable s_aws_input_stream_tester_vtable = {
699698
.seek = s_aws_input_stream_tester_seek,
700699
.read = s_aws_input_stream_tester_read,
701700
.get_status = s_aws_input_stream_tester_get_status,
702701
.get_length = s_aws_input_stream_tester_get_length,
703-
.destroy = s_aws_input_stream_tester_destroy,
704702
};
705703

706704
struct aws_input_stream *aws_input_stream_new_tester(struct aws_allocator *alloc, struct aws_byte_cursor cursor) {
707705

708-
struct aws_input_stream *stream = NULL;
709-
struct aws_input_stream_tester *impl = NULL;
710-
aws_mem_acquire_many(
711-
alloc, 2, &stream, sizeof(struct aws_input_stream), &impl, sizeof(struct aws_input_stream_tester));
712-
AWS_FATAL_ASSERT(stream);
713-
714-
AWS_ZERO_STRUCT(*stream);
715-
AWS_ZERO_STRUCT(*impl);
716-
717-
stream->allocator = alloc;
718-
stream->impl = impl;
719-
stream->vtable = &s_aws_input_stream_tester_vtable;
706+
struct aws_input_stream_tester *impl = aws_mem_calloc(alloc, 1, sizeof(struct aws_input_stream_tester));
707+
AWS_FATAL_ASSERT(impl);
720708

721709
impl->max_bytes_per_read = SIZE_MAX;
722710

723711
impl->cursor_stream = aws_input_stream_new_from_cursor(alloc, &cursor);
724712
AWS_FATAL_ASSERT(impl->cursor_stream);
725-
726-
return stream;
713+
impl->allocator = alloc;
714+
impl->base.vtable = &s_aws_input_stream_tester_vtable;
715+
aws_ref_count_init(
716+
&impl->base.ref_count, impl, (aws_simple_completion_callback *)s_aws_input_stream_tester_destroy);
717+
return &impl->base;
727718
}
728719

729720
void aws_input_stream_tester_set_max_bytes_per_read(struct aws_input_stream *input_stream, size_t max_bytes) {
730-
struct aws_input_stream_tester *impl = input_stream->impl;
721+
struct aws_input_stream_tester *impl = AWS_CONTAINER_OF(input_stream, struct aws_input_stream_tester, base);
731722
impl->max_bytes_per_read = max_bytes;
732723
}
733724

734725
void aws_input_stream_tester_set_reading_broken(struct aws_input_stream *input_stream, bool is_broken) {
735-
struct aws_input_stream_tester *impl = input_stream->impl;
726+
struct aws_input_stream_tester *impl = AWS_CONTAINER_OF(input_stream, struct aws_input_stream_tester, base);
736727
impl->is_reading_broken = is_broken;
737728
}

tests/test_connection_monitor.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ static void s_clean_up_monitor_test(void) {
147147
if (request_info) {
148148
aws_http_message_destroy(request_info->request);
149149
aws_http_stream_release(request_info->stream);
150-
aws_input_stream_destroy(request_info->body);
150+
aws_input_stream_release(request_info->body);
151151
}
152152
}
153153

0 commit comments

Comments
 (0)