]> granicus.if.org Git - apache/commitdiff
mod_http2: rest of the fix for output blockage
authorStefan Eissing <icing@apache.org>
Mon, 19 Sep 2016 16:21:42 +0000 (16:21 +0000)
committerStefan Eissing <icing@apache.org>
Mon, 19 Sep 2016 16:21:42 +0000 (16:21 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1761477 13f79535-47bb-0310-9956-ffa450edef68

modules/http2/h2_bucket_beam.c
modules/http2/h2_mplx.c
modules/http2/h2_mplx.h
modules/http2/h2_stream.c
modules/http2/h2_task.c

index 1338ba68b011f3b24f6cf5495f13deefa015aa3f..b1d698e796191195a6ed29f274648d4440454f22 100644 (file)
@@ -223,6 +223,28 @@ static void leave_yellow(h2_bucket_beam *beam, h2_beam_lock *pbl)
     }
 }
 
+static void report_consumption(h2_bucket_beam *beam, int force)
+{
+    if (force || beam->received_bytes != beam->reported_consumed_bytes) {
+        if (beam->consumed_fn) { 
+            beam->consumed_fn(beam->consumed_ctx, beam, beam->received_bytes
+                              - beam->reported_consumed_bytes);
+        }
+        beam->reported_consumed_bytes = beam->received_bytes;
+    }
+}
+
+static void report_production(h2_bucket_beam *beam, int force)
+{
+    if (force || beam->sent_bytes != beam->reported_produced_bytes) {
+        if (beam->produced_fn) { 
+            beam->produced_fn(beam->produced_ctx, beam, beam->sent_bytes
+                              - beam->reported_produced_bytes);
+        }
+        beam->reported_produced_bytes = beam->sent_bytes;
+    }
+}
+
 static apr_off_t calc_buffered(h2_bucket_beam *beam)
 {
     apr_off_t len = 0;
@@ -279,7 +301,9 @@ static apr_status_t r_wait_space(h2_bucket_beam *beam, apr_read_type_e block,
     *premain = calc_space_left(beam);
     while (!beam->aborted && *premain <= 0 
            && (block == APR_BLOCK_READ) && pbl->mutex) {
-        apr_status_t status = wait_cond(beam, pbl->mutex);
+        apr_status_t status;
+        report_production(beam, 1);
+        status = wait_cond(beam, pbl->mutex);
         if (APR_STATUS_IS_TIMEUP(status)) {
             return status;
         }
@@ -356,28 +380,6 @@ static void h2_beam_emitted(h2_bucket_beam *beam, h2_beam_proxy *proxy)
     }
 }
 
-static void report_consumption(h2_bucket_beam *beam, int force)
-{
-    if (force || beam->received_bytes != beam->reported_consumed_bytes) {
-        if (beam->consumed_fn) { 
-            beam->consumed_fn(beam->consumed_ctx, beam, beam->received_bytes
-                              - beam->reported_consumed_bytes);
-        }
-        beam->reported_consumed_bytes = beam->received_bytes;
-    }
-}
-
-static void report_production(h2_bucket_beam *beam, int force)
-{
-    if (force || beam->sent_bytes != beam->reported_produced_bytes) {
-        if (beam->produced_fn) { 
-            beam->produced_fn(beam->produced_ctx, beam, beam->sent_bytes
-                              - beam->reported_produced_bytes);
-        }
-        beam->reported_produced_bytes = beam->sent_bytes;
-    }
-}
-
 static void h2_blist_cleanup(h2_blist *bl)
 {
     apr_bucket *e;
@@ -877,6 +879,9 @@ transfer:
         }
         
         if (transferred) {
+            if (beam->m_cond) {
+                apr_thread_cond_broadcast(beam->m_cond);
+            }
             status = APR_SUCCESS;
         }
         else if (beam->closed) {
@@ -890,6 +895,9 @@ transfer:
             goto transfer;
         }
         else {
+            if (beam->m_cond) {
+                apr_thread_cond_broadcast(beam->m_cond);
+            }
             status = APR_EAGAIN;
         }
 leave:        
index ea574abc4db80e79bcbb76c456be272b5fcc5704..dd0f0fdd29881a3b8ac78dd3e0dc4e4ec7612458 100644 (file)
@@ -545,7 +545,7 @@ static int task_abort_connection(void *ctx, void *val)
     if (task->input.beam) {
         h2_beam_abort(task->input.beam);
     }
-    if (task->output.beam) {
+    if (task->worker_started && !task->worker_done && task->output.beam) {
         h2_beam_abort(task->output.beam);
     }
     return 1;
index 4af0ba3c1385ed7065f391c36b80d57213e6cdf6..b2873e882769df934f5cde8024dc086551513734 100644 (file)
@@ -158,6 +158,8 @@ void h2_mplx_task_done(h2_mplx *m, struct h2_task *task, struct h2_task **ptask)
  */
 apr_uint32_t h2_mplx_shutdown(h2_mplx *m);
 
+int h2_mplx_is_busy(h2_mplx *m);
+
 /*******************************************************************************
  * IO lifetime of streams.
  ******************************************************************************/
index 7004647c0ebea57ff413a133f0fd95543ced52da..02e1a1274139ff65fbaada7c64584d435e0eefb2 100644 (file)
@@ -513,6 +513,9 @@ static apr_status_t fill_buffer(h2_stream *stream, apr_size_t amount)
     }
     status = h2_beam_receive(stream->output, stream->buffer, 
                              APR_NONBLOCK_READ, amount);
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, stream->session->c,
+                  "h2_stream(%ld-%d): beam_received",
+                  stream->session->id, stream->id);
     /* The buckets we reveive are using the stream->buffer pool as
      * lifetime which is exactly what we want since this is stream->pool.
      *
index 285607220c6309edd24df48a66b499560fdb7e25..c22471d27f601d02eb62ca86b2a4b5d9a3c18ab8 100644 (file)
@@ -383,6 +383,11 @@ static apr_status_t send_out(h2_task *task, apr_bucket_brigade* bb)
             h2_task_logio_add_bytes_out(task->c, written);
         }
     }
+    else {
+        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, task->c,
+                      "h2_task(%s): send_out (%ld bytes)", 
+                      task->id, (long)written);
+    }
     return status;
 }
 
@@ -542,8 +547,14 @@ static apr_status_t h2_filter_stream_output(ap_filter_t* filter,
                                             apr_bucket_brigade* brigade)
 {
     h2_task *task = h2_ctx_cget_task(filter->c);
-    AP_DEBUG_ASSERT(task);
-    return output_write(task, filter, brigade);
+    apr_status_t status;
+    
+    ap_assert(task);
+    status = output_write(task, filter, brigade);
+    if (status != APR_SUCCESS) {
+        h2_task_rst(task, H2_ERR_INTERNAL_ERROR);
+    }
+    return status;
 }
 
 static apr_status_t h2_filter_read_response(ap_filter_t* filter,