@@ -407,6 +407,7 @@ static void s_stream_data_write_destroy(
407
407
408
408
AWS_PRECONDITION (stream );
409
409
AWS_PRECONDITION (write );
410
+ AWS_PRECONDITION (!aws_linked_list_node_is_in_list (& stream -> node ));
410
411
if (write -> on_complete ) {
411
412
write -> on_complete (& stream -> base , error_code , write -> user_data );
412
413
}
@@ -682,37 +683,13 @@ static inline bool s_h2_stream_has_outgoing_writes(struct aws_h2_stream *stream)
682
683
return !aws_linked_list_empty (& stream -> thread_data .outgoing_writes );
683
684
}
684
685
685
- static void s_h2_stream_write_data_complete (struct aws_h2_stream * stream , bool * waiting_writes ) {
686
- AWS_PRECONDITION (waiting_writes );
687
- AWS_PRECONDITION (s_h2_stream_has_outgoing_writes (stream ));
688
-
689
- /* finish/clean up the current write operation */
690
- struct aws_linked_list_node * node = aws_linked_list_pop_front (& stream -> thread_data .outgoing_writes );
691
- struct aws_h2_stream_data_write * write_op = AWS_CONTAINER_OF (node , struct aws_h2_stream_data_write , node );
692
- const bool ending_stream = write_op -> end_stream ;
693
- s_stream_data_write_destroy (stream , write_op , AWS_OP_SUCCESS );
694
-
695
- /* check to see if there are more queued writes or stream_end was called */
696
- * waiting_writes = !ending_stream && !s_h2_stream_has_outgoing_writes (stream );
697
- }
698
-
699
686
static struct aws_h2_stream_data_write * s_h2_stream_get_current_write (struct aws_h2_stream * stream ) {
700
687
AWS_PRECONDITION (s_h2_stream_has_outgoing_writes (stream ));
701
688
struct aws_linked_list_node * node = aws_linked_list_front (& stream -> thread_data .outgoing_writes );
702
689
struct aws_h2_stream_data_write * write = AWS_CONTAINER_OF (node , struct aws_h2_stream_data_write , node );
703
690
return write ;
704
691
}
705
692
706
- static struct aws_input_stream * s_h2_stream_get_data_stream (struct aws_h2_stream * stream ) {
707
- struct aws_h2_stream_data_write * write = s_h2_stream_get_current_write (stream );
708
- return write -> data_stream ;
709
- }
710
-
711
- static bool s_h2_stream_does_current_write_end_stream (struct aws_h2_stream * stream ) {
712
- struct aws_h2_stream_data_write * write = s_h2_stream_get_current_write (stream );
713
- return write -> end_stream ;
714
- }
715
-
716
693
int aws_h2_stream_on_activated (struct aws_h2_stream * stream , enum aws_h2_stream_body_state * body_state ) {
717
694
AWS_PRECONDITION_ON_CHANNEL_THREAD (stream );
718
695
@@ -799,12 +776,14 @@ int aws_h2_stream_encode_data_frame(
799
776
}
800
777
801
778
* data_encode_status = AWS_H2_DATA_ENCODE_COMPLETE ;
802
- struct aws_input_stream * input_stream = s_h2_stream_get_data_stream (stream );
779
+ struct aws_h2_stream_data_write * current_write = s_h2_stream_get_current_write (stream );
780
+ struct aws_input_stream * input_stream = current_write -> data_stream ;
803
781
AWS_ASSERT (input_stream );
804
782
805
783
bool input_stream_complete = false;
806
784
bool input_stream_stalled = false;
807
- bool ends_stream = s_h2_stream_does_current_write_end_stream (stream );
785
+ bool input_stream_failed = false;
786
+ bool ends_stream = current_write -> end_stream ;
808
787
if (aws_h2_encode_data_frame (
809
788
encoder ,
810
789
stream -> base .id ,
@@ -815,20 +794,30 @@ int aws_h2_stream_encode_data_frame(
815
794
& connection -> thread_data .window_size_peer ,
816
795
output ,
817
796
& input_stream_complete ,
818
- & input_stream_stalled )) {
797
+ & input_stream_stalled ,
798
+ & input_stream_failed )) {
799
+
800
+ int error_code = aws_last_error ();
801
+
802
+ /* If error cause caused aws_input_stream, report that specific error in its write-completion callback */
803
+ if (input_stream_failed ) {
804
+ aws_linked_list_remove (& current_write -> node );
805
+ s_stream_data_write_destroy (stream , current_write , error_code );
806
+ }
819
807
820
808
/* Failed to write DATA, treat it as a Stream Error */
821
- AWS_H2_STREAM_LOGF (ERROR , stream , "Error encoding stream DATA, %s" , aws_error_name (aws_last_error () ));
822
- struct aws_h2err returned_h2err = s_send_rst_and_close_stream (stream , aws_h2err_from_last_error ( ));
809
+ AWS_H2_STREAM_LOGF (ERROR , stream , "Error encoding stream DATA, %s" , aws_error_name (error_code ));
810
+ struct aws_h2err returned_h2err = s_send_rst_and_close_stream (stream , aws_h2err_from_aws_code ( error_code ));
823
811
if (aws_h2err_failed (returned_h2err )) {
824
812
aws_h2_connection_shutdown_due_to_write_err (connection , returned_h2err .aws_code );
825
813
}
826
814
return AWS_OP_SUCCESS ;
827
815
}
828
816
829
- bool waiting_writes = false;
830
817
if (input_stream_complete ) {
831
- s_h2_stream_write_data_complete (stream , & waiting_writes );
818
+ /* finish/clean up the current write operation */
819
+ aws_linked_list_remove (& current_write -> node );
820
+ s_stream_data_write_destroy (stream , current_write , AWS_ERROR_SUCCESS );
832
821
}
833
822
834
823
/*
@@ -867,10 +856,11 @@ int aws_h2_stream_encode_data_frame(
867
856
* from outgoing list */
868
857
* data_encode_status = AWS_H2_DATA_ENCODE_ONGOING_WINDOW_STALLED ;
869
858
}
870
- if (waiting_writes ) {
859
+ if (! s_h2_stream_has_outgoing_writes ( stream ) ) {
871
860
/* if window stalled and we waiting for manual writes, we take waiting writes status, which will be handled
872
861
* properly if more writes coming, but windows is still stalled. But not the other way around. */
873
862
AWS_ASSERT (input_stream_complete );
863
+ AWS_ASSERT (!ends_stream );
874
864
* data_encode_status = AWS_H2_DATA_ENCODE_ONGOING_WAITING_FOR_WRITES ;
875
865
}
876
866
}
0 commit comments