]> granicus.if.org Git - apache/commitdiff
when stream gets reset by client, forward info to mplx and fail writes
authorStefan Eissing <icing@apache.org>
Mon, 12 Oct 2015 14:14:36 +0000 (14:14 +0000)
committerStefan Eissing <icing@apache.org>
Mon, 12 Oct 2015 14:14:36 +0000 (14:14 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1708124 13f79535-47bb-0310-9956-ffa450edef68

modules/http2/h2_io_set.c
modules/http2/h2_io_set.h
modules/http2/h2_mplx.c
modules/http2/h2_session.c

index 91afde8f1f5e2c55f6b12a5fbecaa7797a2951d1..74ab508fefe87591de4c3f05f6457d88ce022061 100644 (file)
@@ -78,19 +78,6 @@ h2_io *h2_io_set_get(h2_io_set *sp, int stream_id)
     return ps? *ps : NULL;
 }
 
-h2_io *h2_io_set_get_highest_prio(h2_io_set *set)
-{
-    h2_io *highest = NULL;
-    int i;
-    for (i = 0; i < set->list->nelts; ++i) {
-        h2_io *io = h2_io_IDX(set->list, i);
-        if (!highest /*|| io-prio even higher */ ) {
-            highest = io;
-        }
-    }
-    return highest;
-}
-
 static void h2_io_set_sort(h2_io_set *sp)
 {
     qsort(sp->list->elts, sp->list->nelts, sp->list->elt_size, 
@@ -118,28 +105,46 @@ apr_status_t h2_io_set_add(h2_io_set *sp, h2_io *io)
     return APR_SUCCESS;
 }
 
+static void remove_idx(h2_io_set *sp, int idx)
+{
+    int n;
+    --sp->list->nelts;
+    n = sp->list->nelts - idx;
+    if (n > 0) {
+        /* Close the hole in the array by moving the upper
+         * parts down one step.
+         */
+        h2_io **selts = (h2_io**)sp->list->elts;
+        memmove(selts + idx, selts + idx + 1, n * sizeof(h2_io*));
+    }
+}
+
 h2_io *h2_io_set_remove(h2_io_set *sp, h2_io *io)
 {
     int i;
     for (i = 0; i < sp->list->nelts; ++i) {
         h2_io *e = h2_io_IDX(sp->list, i);
         if (e == io) {
-            int n;
-            --sp->list->nelts;
-            n = sp->list->nelts - i;
-            if (n > 0) {
-                /* Close the hole in the array by moving the upper
-                 * parts down one step.
-                 */
-                h2_io **selts = (h2_io**)sp->list->elts;
-                memmove(selts+i, selts+i+1, n * sizeof(h2_io*));
-            }
+            remove_idx(sp, i);
             return e;
         }
     }
     return NULL;
 }
 
+h2_io *h2_io_set_pop_highest_prio(h2_io_set *set)
+{
+    /* For now, this just removes the first element in the set.
+     * the name is misleading...
+     */
+    if (set->list->nelts > 0) {
+        h2_io *io = h2_io_IDX(set->list, 0);
+        remove_idx(set, 0);
+        return io;
+    }
+    return NULL;
+}
+
 void h2_io_set_destroy_all(h2_io_set *sp)
 {
     int i;
index a9c6546c7015a9ada43298a33345cb4abcca4e86..5e7555af92e35bacef141c5a7f86c023ce28ba9c 100644 (file)
@@ -30,7 +30,6 @@ void h2_io_set_destroy(h2_io_set *set);
 
 apr_status_t h2_io_set_add(h2_io_set *set, struct h2_io *io);
 h2_io *h2_io_set_get(h2_io_set *set, int stream_id);
-h2_io *h2_io_set_get_highest_prio(h2_io_set *set);
 h2_io *h2_io_set_remove(h2_io_set *set, struct h2_io *io);
 
 void h2_io_set_remove_all(h2_io_set *set);
@@ -44,4 +43,6 @@ typedef int h2_io_set_iter_fn(void *ctx, struct h2_io *io);
 void h2_io_set_iter(h2_io_set *set,
                            h2_io_set_iter_fn *iter, void *ctx);
 
+h2_io *h2_io_set_pop_highest_prio(h2_io_set *set);
+
 #endif /* defined(__mod_h2__h2_io_set__) */
index 3b5207677c772fa58eb48b5ae3a645b09c61b957..6c4ae9f4c4e7b8ec210da482a9651c66c5abfb9a 100644 (file)
@@ -299,6 +299,13 @@ apr_status_t h2_mplx_cleanup_stream(h2_mplx *m, h2_stream *stream)
             stream_destroy(m, stream, io);
         }
         else {
+            if (stream->rst_error) {
+                /* Forward error code to fail any further attempt to
+                 * write to io */
+                h2_io_rst(io, stream->rst_error);
+            }
+            /* Remove io from ready set (if there), since we will never submit it */
+            h2_io_set_remove(m->ready_ios, io);
             /* Add stream to closed set for cleanup when task is done */
             h2_stream_set_add(m->closed, stream);
         }
@@ -502,9 +509,8 @@ h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_stream_set *streams)
     }
     status = apr_thread_mutex_lock(m->lock);
     if (APR_SUCCESS == status) {
-        h2_io *io = h2_io_set_get_highest_prio(m->ready_ios);
+        h2_io *io = h2_io_set_pop_highest_prio(m->ready_ios);
         if (io) {
-            
             stream = h2_stream_set_get(streams, io->id);
             if (stream) {
                 if (io->rst_error) {
@@ -515,15 +521,18 @@ h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_stream_set *streams)
                     h2_stream_set_response(stream, io->response, io->bbout);
                 }
                 
-                h2_io_set_remove(m->ready_ios, io);
                 if (io->output_drained) {
                     apr_thread_cond_signal(io->output_drained);
                 }
             }
             else {
-                ap_log_cerror(APLOG_MARK, APLOG_WARNING, APR_NOTFOUND, m->c,
-                              APLOGNO(02953) "h2_mplx(%ld): stream for response %d",
+                ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, APLOGNO(02953) 
+                              "h2_mplx(%ld): stream for response %d not found",
                               m->id, io->id);
+                /* We have the io ready, but the stream has gone away, maybe
+                 * reset by the client. Should no longer happen since such
+                 * streams should clear io's from the ready queue.
+                 */
             }
         }
         apr_thread_mutex_unlock(m->lock);
index 80336081d4d08e1963a554628f5abaac90932794..b8fa885a2bf699f8de29d76ca521fc6b962a1af9 100644 (file)
@@ -243,6 +243,7 @@ static apr_status_t stream_destroy(h2_session *session,
                       "h2_stream(%ld-%d): closing with err=%d %s", 
                       session->id, (int)stream->id, (int)error_code,
                       nghttp2_strerror(error_code));
+        h2_stream_rst(stream, error_code);
     }
     
     h2_stream_set_remove(session->streams, stream);