| 975 | } |
| 976 | |
| 977 | static void s_c2_done(h2_mplx *m, conn_rec *c2, h2_conn_ctx_t *conn_ctx) |
| 978 | { |
| 979 | h2_stream *stream; |
| 980 | |
| 981 | ap_assert(conn_ctx); |
| 982 | ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2, |
| 983 | "h2_mplx(%s-%d): c2 done", conn_ctx->id, conn_ctx->stream_id); |
| 984 | |
| 985 | AP_DEBUG_ASSERT(apr_atomic_read32(&conn_ctx->done) == 0); |
| 986 | apr_atomic_set32(&conn_ctx->done, 1); |
| 987 | conn_ctx->done_at = apr_time_now(); |
| 988 | ++c2->keepalives; |
| 989 | /* From here on, the final handling of c2 is done by c1 processing. |
| 990 | * Which means we can give it c1's scoreboard handle for updates. */ |
| 991 | c2->sbh = m->c1->sbh; |
| 992 | #if AP_MODULE_MAGIC_AT_LEAST(20211221, 29) |
| 993 | ap_set_time_process_request(c2->sbh,conn_ctx->started_at,conn_ctx->done_at); |
| 994 | #endif |
| 995 | ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2, |
| 996 | "h2_mplx(%s-%d): request done, %f ms elapsed", |
| 997 | conn_ctx->id, conn_ctx->stream_id, |
| 998 | (conn_ctx->done_at - conn_ctx->started_at) / 1000.0); |
| 999 | |
| 1000 | if (!conn_ctx->has_final_response) { |
| 1001 | ap_log_cerror(APLOG_MARK, APLOG_TRACE1, conn_ctx->last_err, c2, |
| 1002 | "h2_c2(%s-%d): processing finished without final response", |
| 1003 | conn_ctx->id, conn_ctx->stream_id); |
| 1004 | c2->aborted = 1; |
| 1005 | if (conn_ctx->beam_out) |
| 1006 | h2_beam_abort(conn_ctx->beam_out, c2); |
| 1007 | } |
| 1008 | else if (!conn_ctx->beam_out || !h2_beam_is_complete(conn_ctx->beam_out)) { |
| 1009 | ap_log_cerror(APLOG_MARK, APLOG_TRACE1, conn_ctx->last_err, c2, |
| 1010 | "h2_c2(%s-%d): processing finished with incomplete output", |
| 1011 | conn_ctx->id, conn_ctx->stream_id); |
| 1012 | c2->aborted = 1; |
| 1013 | h2_beam_abort(conn_ctx->beam_out, c2); |
| 1014 | } |
| 1015 | else if (!c2->aborted) { |
| 1016 | s_mplx_be_happy(m, c2, conn_ctx); |
| 1017 | } |
| 1018 | |
| 1019 | stream = h2_ihash_get(m->streams, conn_ctx->stream_id); |
| 1020 | if (stream) { |
| 1021 | /* stream not done yet. trigger a potential polling on the output |
| 1022 | * since nothing more will happening here. */ |
| 1023 | ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2, |
| 1024 | H2_STRM_MSG(stream, "c2_done, stream open")); |
| 1025 | c2_beam_output_write_notify(c2, NULL); |
| 1026 | } |
| 1027 | else if ((stream = h2_ihash_get(m->shold, conn_ctx->stream_id)) != NULL) { |
| 1028 | /* stream is done, was just waiting for this. */ |
| 1029 | ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2, |
| 1030 | H2_STRM_MSG(stream, "c2_done, in hold")); |
| 1031 | c1c2_stream_joined(m, stream); |
| 1032 | } |
| 1033 | else { |
| 1034 | int i; |
no test coverage detected