@@ -407,6 +407,7 @@ static void s_stream_data_write_destroy(
407407
408408 AWS_PRECONDITION (stream );
409409 AWS_PRECONDITION (write );
410+ AWS_PRECONDITION (!aws_linked_list_node_is_in_list (& stream -> node ));
410411 if (write -> on_complete ) {
411412 write -> on_complete (& stream -> base , error_code , write -> user_data );
412413 }
@@ -682,37 +683,13 @@ static inline bool s_h2_stream_has_outgoing_writes(struct aws_h2_stream *stream)
682683 return !aws_linked_list_empty (& stream -> thread_data .outgoing_writes );
683684}
684685
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-
699686static struct aws_h2_stream_data_write * s_h2_stream_get_current_write (struct aws_h2_stream * stream ) {
700687 AWS_PRECONDITION (s_h2_stream_has_outgoing_writes (stream ));
701688 struct aws_linked_list_node * node = aws_linked_list_front (& stream -> thread_data .outgoing_writes );
702689 struct aws_h2_stream_data_write * write = AWS_CONTAINER_OF (node , struct aws_h2_stream_data_write , node );
703690 return write ;
704691}
705692
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-
716693int aws_h2_stream_on_activated (struct aws_h2_stream * stream , enum aws_h2_stream_body_state * body_state ) {
717694 AWS_PRECONDITION_ON_CHANNEL_THREAD (stream );
718695
@@ -799,12 +776,14 @@ int aws_h2_stream_encode_data_frame(
799776 }
800777
801778 * 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 ;
803781 AWS_ASSERT (input_stream );
804782
805783 bool input_stream_complete = false;
806784 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 ;
808787 if (aws_h2_encode_data_frame (
809788 encoder ,
810789 stream -> base .id ,
@@ -815,20 +794,30 @@ int aws_h2_stream_encode_data_frame(
815794 & connection -> thread_data .window_size_peer ,
816795 output ,
817796 & 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+ }
819807
820808 /* 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 ));
823811 if (aws_h2err_failed (returned_h2err )) {
824812 aws_h2_connection_shutdown_due_to_write_err (connection , returned_h2err .aws_code );
825813 }
826814 return AWS_OP_SUCCESS ;
827815 }
828816
829- bool waiting_writes = false;
830817 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 );
832821 }
833822
834823 /*
@@ -867,10 +856,11 @@ int aws_h2_stream_encode_data_frame(
867856 * from outgoing list */
868857 * data_encode_status = AWS_H2_DATA_ENCODE_ONGOING_WINDOW_STALLED ;
869858 }
870- if (waiting_writes ) {
859+ if (! s_h2_stream_has_outgoing_writes ( stream ) ) {
871860 /* if window stalled and we waiting for manual writes, we take waiting writes status, which will be handled
872861 * properly if more writes coming, but windows is still stalled. But not the other way around. */
873862 AWS_ASSERT (input_stream_complete );
863+ AWS_ASSERT (!ends_stream );
874864 * data_encode_status = AWS_H2_DATA_ENCODE_ONGOING_WAITING_FOR_WRITES ;
875865 }
876866 }
0 commit comments