]> granicus.if.org Git - apache/commitdiff
goodbye h2_stream_set, hello h2_ihash in h2_util
authorStefan Eissing <icing@apache.org>
Thu, 25 Feb 2016 13:14:30 +0000 (13:14 +0000)
committerStefan Eissing <icing@apache.org>
Thu, 25 Feb 2016 13:14:30 +0000 (13:14 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1732295 13f79535-47bb-0310-9956-ffa450edef68

17 files changed:
CMakeLists.txt
modules/http2/NWGNUmod_http2
modules/http2/config2.m4
modules/http2/h2_conn.c
modules/http2/h2_filter.c
modules/http2/h2_mplx.c
modules/http2/h2_mplx.h
modules/http2/h2_session.c
modules/http2/h2_session.h
modules/http2/h2_stream.c
modules/http2/h2_stream.h
modules/http2/h2_stream_set.c [deleted file]
modules/http2/h2_stream_set.h [deleted file]
modules/http2/h2_util.c
modules/http2/h2_util.h
modules/http2/mod_http2.dsp
modules/http2/mod_proxy_http2.c

index d9fc914a38b8eba98600827a193a0ad70c98e5ca..bd3fe405f28f24cba555a1ec6bed2e454b74dfcf 100644 (file)
@@ -407,7 +407,7 @@ SET(mod_http2_extra_sources
   modules/http2/h2_mplx.c            modules/http2/h2_push.c
   modules/http2/h2_request.c         modules/http2/h2_response.c
   modules/http2/h2_session.c         modules/http2/h2_stream.c 
-  modules/http2/h2_stream_set.c      modules/http2/h2_switch.c
+  modules/http2/h2_switch.c
   modules/http2/h2_task.c            modules/http2/h2_task_input.c
   modules/http2/h2_task_output.c     modules/http2/h2_int_queue.c
   modules/http2/h2_util.c            modules/http2/h2_worker.c
index 0e53b4ae1fb160685819612d6d2ea7077e6c08f8..12811bd2703575cee08133c0f2fe4142e08f9e51 100644 (file)
@@ -203,7 +203,6 @@ FILES_nlm_objs = \
        $(OBJDIR)/h2_response.o \
        $(OBJDIR)/h2_session.o \
        $(OBJDIR)/h2_stream.o \
-       $(OBJDIR)/h2_stream_set.o \
        $(OBJDIR)/h2_switch.o \
        $(OBJDIR)/h2_task.o \
        $(OBJDIR)/h2_task_input.o \
index 85a635e6b3459425d629890f9823de4c7e8f1b08..b47b2d21923de01062906c2586eaf9d2d9d39cad 100644 (file)
@@ -38,7 +38,6 @@ h2_request.lo dnl
 h2_response.lo dnl
 h2_session.lo dnl
 h2_stream.lo dnl
-h2_stream_set.lo dnl
 h2_switch.lo dnl
 h2_task.lo dnl
 h2_task_input.lo dnl
index ac0379b32922073492a2e0a02318221cfd70e255..f6f814e6346be81e7a732ab19c8a9fe44f23d593 100644 (file)
@@ -32,7 +32,6 @@
 #include "h2_mplx.h"
 #include "h2_session.h"
 #include "h2_stream.h"
-#include "h2_stream_set.h"
 #include "h2_h2.h"
 #include "h2_task.h"
 #include "h2_worker.h"
index 8330ace15048185d2fd0778f069c72cfafba113b..751480e73fe9545c0c4cedcbfcae66384eb99c25 100644 (file)
@@ -28,7 +28,6 @@
 #include "h2_push.h"
 #include "h2_task.h"
 #include "h2_stream.h"
-#include "h2_stream_set.h"
 #include "h2_request.h"
 #include "h2_response.h"
 #include "h2_session.h"
@@ -217,7 +216,7 @@ static apr_status_t h2_sos_h2_status_buffer(h2_sos *sos, apr_bucket_brigade *bb)
     bbout("  \"session_id\": %ld,\n", (long)session->id);
     bbout("  \"streams_max\": %d,\n", (int)session->max_stream_count);
     bbout("  \"this_stream\": %d,\n", stream->id);
-    bbout("  \"streams_open\": %d,\n", (int)h2_stream_set_size(session->streams));
+    bbout("  \"streams_open\": %d,\n", (int)h2_ihash_count(session->streams));
     bbout("  \"max_stream_started\": %d,\n", mplx->max_stream_started);
     bbout("  \"requests_received\": %d,\n", session->requests_received);
     bbout("  \"responses_submitted\": %d,\n", session->responses_submitted);
index 47e222f3d68dfef297395fb999885aff94e3e2a0..90765f58d79b8a240151d780756daf123aadd9da 100644 (file)
@@ -41,7 +41,6 @@
 #include "h2_mplx.h"
 #include "h2_request.h"
 #include "h2_stream.h"
-#include "h2_stream_set.h"
 #include "h2_task.h"
 #include "h2_task_input.h"
 #include "h2_task_output.h"
@@ -640,7 +639,7 @@ apr_status_t h2_mplx_out_read_to(h2_mplx *m, int stream_id,
     return status;
 }
 
-h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_stream_set *streams)
+h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_ihash_t *streams)
 {
     apr_status_t status;
     h2_stream *stream = NULL;
@@ -650,7 +649,7 @@ h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_stream_set *streams)
     if ((status = enter_mutex(m, &acquired)) == APR_SUCCESS) {
         h2_io *io = h2_io_set_shift(m->ready_ios);
         if (io && !m->aborted) {
-            stream = h2_stream_set_get(streams, io->id);
+            stream = h2_ihash_get(streams, io->id);
             if (stream) {
                 if (io->rst_error) {
                     h2_stream_rst(stream, io->rst_error);
index aebd672e046d5ef270f6b8836391dcd8cdb0a7f0..12bb2d39ace719412a093b2b67902ec98e02da55 100644 (file)
@@ -38,6 +38,7 @@ struct apr_pool_t;
 struct apr_thread_mutex_t;
 struct apr_thread_cond_t;
 struct h2_config;
+struct h2_ihash_t;
 struct h2_response;
 struct h2_task;
 struct h2_stream;
@@ -45,7 +46,6 @@ struct h2_request;
 struct h2_io_set;
 struct apr_thread_cond_t;
 struct h2_workers;
-struct h2_stream_set;
 struct h2_int_queue;
 struct h2_req_engine;
 
@@ -267,7 +267,7 @@ apr_status_t h2_mplx_in_update_windows(h2_mplx *m);
  * @param bb the brigade to place any existing repsonse body data into
  */
 struct h2_stream *h2_mplx_next_submit(h2_mplx *m, 
-                                      struct h2_stream_set *streams);
+                                      struct h2_ihash_t *streams);
 
 /**
  * Reads output data from the given stream. Will never block, but
index 9b24e621c4dfaca9882adb6a62adf44886e33f54..0be64b8cd73e36459073a6192e8c5feaeca2831d 100644 (file)
@@ -38,7 +38,6 @@
 #include "h2_request.h"
 #include "h2_response.h"
 #include "h2_stream.h"
-#include "h2_stream_set.h"
 #include "h2_from_h1.h"
 #include "h2_task.h"
 #include "h2_session.h"
@@ -94,7 +93,7 @@ h2_stream *h2_session_open_stream(h2_session *session, int stream_id)
     
     stream = h2_stream_open(stream_id, stream_pool, session);
     
-    h2_stream_set_add(session->streams, stream);
+    h2_ihash_add(session->streams, stream);
     if (H2_STREAM_CLIENT_INITIATED(stream_id)
         && stream_id > session->max_stream_received) {
         ++session->requests_received;
@@ -666,17 +665,13 @@ static void h2_session_destroy(h2_session *session)
     if (APLOGctrace1(session->c)) {
         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
                       "h2_session(%ld): destroy, %d streams open",
-                      session->id, (int)h2_stream_set_size(session->streams));
+                      session->id, (int)h2_ihash_count(session->streams));
     }
     if (session->mplx) {
         h2_mplx_set_consumed_cb(session->mplx, NULL, NULL);
         h2_mplx_release_and_join(session->mplx, session->iowait);
         session->mplx = NULL;
     }
-    if (session->streams) {
-        h2_stream_set_destroy(session->streams);
-        session->streams = NULL;
-    }
     if (session->pool) {
         apr_pool_destroy(session->pool);
     }
@@ -822,8 +817,7 @@ static h2_session *h2_session_create_int(conn_rec *c,
             return NULL;
         }
         
-        session->streams = h2_stream_set_create(session->pool, session->max_stream_count);
-        
+        session->streams = h2_ihash_create(session->pool,offsetof(h2_stream, id));
         session->workers = workers;
         session->mplx = h2_mplx_create(c, session->pool, session->config, 
                                        session->s->timeout, workers);
@@ -1032,8 +1026,9 @@ typedef struct {
     int resume_count;
 } resume_ctx;
 
-static int resume_on_data(void *ctx, h2_stream *stream)
+static int resume_on_data(void *ctx, void *val)
 {
+    h2_stream *stream = val;
     resume_ctx *rctx = (resume_ctx*)ctx;
     h2_session *session = rctx->session;
     AP_DEBUG_ASSERT(session);
@@ -1059,7 +1054,7 @@ static int resume_on_data(void *ctx, h2_stream *stream)
 static int h2_session_resume_streams_with_data(h2_session *session)
 {
     AP_DEBUG_ASSERT(session);
-    if (!h2_stream_set_is_empty(session->streams)
+    if (!h2_ihash_is_empty(session->streams)
         && session->mplx && !session->mplx->aborted) {
         resume_ctx ctx;
         
@@ -1068,7 +1063,7 @@ static int h2_session_resume_streams_with_data(h2_session *session)
 
         /* Resume all streams where we have data in the out queue and
          * which had been suspended before. */
-        h2_stream_set_iter(session->streams, resume_on_data, &ctx);
+        h2_ihash_iter(session->streams, resume_on_data, &ctx);
         return ctx.resume_count;
     }
     return 0;
@@ -1077,7 +1072,7 @@ static int h2_session_resume_streams_with_data(h2_session *session)
 h2_stream *h2_session_get_stream(h2_session *session, int stream_id)
 {
     if (!session->last_stream || stream_id != session->last_stream->id) {
-        session->last_stream = h2_stream_set_get(session->streams, stream_id);
+        session->last_stream = h2_ihash_get(session->streams, stream_id);
     }
     return session->last_stream;
 }
@@ -1447,7 +1442,7 @@ apr_status_t h2_session_stream_destroy(h2_session *session, h2_stream *stream)
         session->last_stream = NULL;
     }
     if (session->streams) {
-        h2_stream_set_remove(session->streams, stream->id);
+        h2_ihash_remove(session->streams, stream->id);
     }
     h2_stream_destroy(stream);
     
@@ -1592,12 +1587,46 @@ static apr_status_t h2_session_read(h2_session *session, int block)
     return rstatus;
 }
 
+static int unsubmitted_iter(void *ctx, void *val)
+{
+    h2_stream *stream = val;
+    if (h2_stream_needs_submit(stream)) {
+        *((int *)ctx) = 1;
+        return 0;
+    }
+    return 1;
+}
+
+static int has_unsubmitted_streams(h2_session *session)
+{
+    int has_unsubmitted = 0;
+    h2_ihash_iter(session->streams, unsubmitted_iter, &has_unsubmitted);
+    return has_unsubmitted;
+}
+
+static int suspended_iter(void *ctx, void *val)
+{
+    h2_stream *stream = val;
+    if (h2_stream_is_suspended(stream)) {
+        *((int *)ctx) = 1;
+        return 0;
+    }
+    return 1;
+}
+
+static int has_suspended_streams(h2_session *session)
+{
+    int has_suspended = 0;
+    h2_ihash_iter(session->streams, suspended_iter, &has_suspended);
+    return has_suspended;
+}
+
 static apr_status_t h2_session_submit(h2_session *session)
 {
     apr_status_t status = APR_EAGAIN;
     h2_stream *stream;
     
-    if (h2_stream_set_has_unsubmitted(session->streams)) {
+    if (has_unsubmitted_streams(session)) {
         /* If we have responses ready, submit them now. */
         while ((stream = h2_mplx_next_submit(session->mplx, session->streams))) {
             status = submit_response(session, stream);
@@ -1766,7 +1795,7 @@ static void h2_session_ev_no_io(h2_session *session, int arg, const char *msg)
              * CPU cycles. Ideally, we'd like to do a blocking read, but that
              * is not possible if we have scheduled tasks and wait
              * for them to produce something. */
-            if (h2_stream_set_is_empty(session->streams)) {
+            if (h2_ihash_is_empty(session->streams)) {
                 if (!is_accepting_streams(session)) {
                     /* We are no longer accepting new streams and have
                      * finished processing existing ones. Time to leave. */
@@ -1782,8 +1811,8 @@ static void h2_session_ev_no_io(h2_session *session, int arg, const char *msg)
                                            session->s->timeout) + apr_time_now();
                 }
             }
-            else if (!h2_stream_set_has_unsubmitted(session->streams)
-                     && !h2_stream_set_has_suspended(session->streams)) {
+            else if (!has_unsubmitted_streams(session)
+                     && !has_suspended_streams(session)) {
                 /* none of our streams is waiting for a response or
                  * new output data from task processing, 
                  * switch to blocking reads. We are probably waiting on
@@ -1927,7 +1956,7 @@ static void update_child_status(h2_session *session, int status, const char *msg
     apr_snprintf(session->status, sizeof(session->status),
                  "%s, streams: %d/%d/%d/%d/%d (open/recv/resp/push/rst)", 
                  msg? msg : "-",
-                 (int)h2_stream_set_size(session->streams), 
+                 (int)h2_ihash_count(session->streams), 
                  (int)session->requests_received,
                  (int)session->responses_submitted,
                  (int)session->pushes_submitted,
@@ -1982,7 +2011,7 @@ apr_status_t h2_session_process(h2_session *session, int async)
                 break;
                 
             case H2_SESSION_ST_IDLE:
-                no_streams = h2_stream_set_is_empty(session->streams);
+                no_streams = h2_ihash_is_empty(session->streams);
                 update_child_status(session, (no_streams? SERVER_BUSY_KEEPALIVE
                                               : SERVER_BUSY_READ), "idle");
                 if (async && !session->r && session->requests_received && no_streams) {
@@ -2066,7 +2095,7 @@ apr_status_t h2_session_process(h2_session *session, int async)
                     }
                 }
                 
-                if (!h2_stream_set_is_empty(session->streams)) {
+                if (!h2_ihash_is_empty(session->streams)) {
                     /* resume any streams for which data is available again */
                     h2_session_resume_streams_with_data(session);
                     /* Submit any responses/push_promises that are ready */
index 118be3c95452f9868a18e79d067600382e7fad6e..d07ae4cc081b29b8d1c69dcec43f3f8b67a43692 100644 (file)
@@ -44,6 +44,7 @@ struct apr_thread_cond_t;
 struct h2_ctx;
 struct h2_config;
 struct h2_filter_cin;
+struct h2_ihash_t;
 struct h2_mplx;
 struct h2_priority;
 struct h2_push;
@@ -118,7 +119,7 @@ typedef struct h2_session {
     struct h2_mplx *mplx;           /* multiplexer for stream data */
     
     struct h2_stream *last_stream;  /* last stream worked with */
-    struct h2_stream_set *streams;  /* streams handled by this session */
+    struct h2_ihash_t *streams;     /* streams handled by this session */
     
     apr_pool_t *spare;              /* spare stream pool */
     
index fc2d021ed817e8ed24bc8606fa7396ea6c573b3d..8af65673a4c4ef1a33ee58979782917a367ee6c0 100644 (file)
@@ -120,7 +120,7 @@ static int close_output(h2_stream *stream)
     return 1;
 }
 
-static int input_open(h2_stream *stream) 
+static int input_open(const h2_stream *stream) 
 {
     switch (stream->state) {
         case H2_STREAM_ST_OPEN:
@@ -328,7 +328,7 @@ apr_status_t h2_stream_schedule(h2_stream *stream, int eos, int push_enabled,
     return status;
 }
 
-int h2_stream_is_scheduled(h2_stream *stream)
+int h2_stream_is_scheduled(const h2_stream *stream)
 {
     return stream->scheduled;
 }
@@ -435,7 +435,7 @@ void h2_stream_set_suspended(h2_stream *stream, int suspended)
                   stream->session->id, stream->id, stream->suspended);
 }
 
-int h2_stream_is_suspended(h2_stream *stream)
+int h2_stream_is_suspended(const h2_stream *stream)
 {
     AP_DEBUG_ASSERT(stream);
     return stream->suspended;
@@ -479,12 +479,12 @@ apr_status_t h2_stream_read_to(h2_stream *stream, apr_bucket_brigade *bb,
     return stream->sos->read_to(stream->sos, bb, plen, peos);
 }
 
-int h2_stream_input_is_open(h2_stream *stream) 
+int h2_stream_input_is_open(const h2_stream *stream) 
 {
     return input_open(stream);
 }
 
-int h2_stream_needs_submit(h2_stream *stream)
+int h2_stream_needs_submit(const h2_stream *stream)
 {
     switch (stream->state) {
         case H2_STREAM_ST_OPEN:
index e3d71a3f9b75cf4f048a63a4191a226598ffdf0c..7d724259fa51c1989c7e128ce94ae2809a63342e 100644 (file)
@@ -183,7 +183,7 @@ apr_status_t h2_stream_schedule(h2_stream *stream, int eos, int push_enabled,
  * @param stream the stream to check on
  * @return != 0 iff stream has been scheduled
  */
-int h2_stream_is_scheduled(h2_stream *stream);
+int h2_stream_is_scheduled(const h2_stream *stream);
 
 struct h2_response *h2_stream_get_response(h2_stream *stream);
 
@@ -270,21 +270,21 @@ void h2_stream_set_suspended(h2_stream *stream, int suspended);
  * @param stream the stream to check
  * @return != 0 iff stream is suspended.
  */
-int h2_stream_is_suspended(h2_stream *stream);
+int h2_stream_is_suspended(const h2_stream *stream);
 
 /**
  * Check if the stream has open input.
  * @param stream the stream to check
  * @return != 0 iff stream has open input.
  */
-int h2_stream_input_is_open(h2_stream *stream);
+int h2_stream_input_is_open(const h2_stream *stream);
 
 /**
  * Check if the stream has not submitted a response or RST yet.
  * @param stream the stream to check
  * @return != 0 iff stream has not submitted a response or RST.
  */
-int h2_stream_needs_submit(h2_stream *stream);
+int h2_stream_needs_submit(const h2_stream *stream);
 
 /**
  * Submit any server push promises on this stream and schedule
diff --git a/modules/http2/h2_stream_set.c b/modules/http2/h2_stream_set.c
deleted file mode 100644 (file)
index aa0f8c6..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <assert.h>
-#include <stddef.h>
-
-#include <apr_hash.h>
-#include <apr_strings.h>
-
-#include <httpd.h>
-#include <http_log.h>
-
-#include "h2_private.h"
-#include "h2_stream.h"
-#include "h2_stream_set.h"
-
-
-struct h2_stream_set {
-    apr_hash_t *hash;
-};
-
-static unsigned int stream_hash(const char *key, apr_ssize_t *klen)
-{
-    return (unsigned int)(*((int*)key));
-}
-
-h2_stream_set *h2_stream_set_create(apr_pool_t *pool, int max)
-{
-    h2_stream_set *sp = apr_pcalloc(pool, sizeof(h2_stream_set));
-    sp->hash = apr_hash_make_custom(pool, stream_hash);
-
-    return sp;
-}
-
-void h2_stream_set_destroy(h2_stream_set *sp)
-{
-    (void)sp;
-}
-
-h2_stream *h2_stream_set_get(h2_stream_set *sp, int stream_id)
-{
-    return apr_hash_get(sp->hash, &stream_id, sizeof(stream_id));
-}
-
-void h2_stream_set_add(h2_stream_set *sp, h2_stream *stream)
-{
-    apr_hash_set(sp->hash, &stream->id, sizeof(stream->id), stream);
-}
-
-void h2_stream_set_remove(h2_stream_set *sp, int stream_id)
-{
-    apr_hash_set(sp->hash, &stream_id, sizeof(stream_id), NULL);
-}
-
-int h2_stream_set_is_empty(h2_stream_set *sp)
-{
-    return apr_hash_count(sp->hash) == 0;
-}
-
-apr_size_t h2_stream_set_size(h2_stream_set *sp)
-{
-    return apr_hash_count(sp->hash);
-}
-
-typedef struct {
-    h2_stream_set_iter_fn *iter;
-    void *ctx;
-} iter_ctx;
-
-static int hash_iter(void *ctx, const void *key, apr_ssize_t klen, 
-                     const void *val)
-{
-    iter_ctx *ictx = ctx;
-    return ictx->iter(ictx->ctx, (h2_stream*)val);
-}
-
-void h2_stream_set_iter(h2_stream_set *sp,
-                        h2_stream_set_iter_fn *iter, void *ctx)
-{
-    iter_ctx ictx;
-    ictx.iter = iter;
-    ictx.ctx = ctx;
-    apr_hash_do(hash_iter, &ictx, sp->hash);
-}
-
-static int unsubmitted_iter(void *ctx, h2_stream *stream)
-{
-    if (h2_stream_needs_submit(stream)) {
-        *((int *)ctx) = 1;
-        return 0;
-    }
-    return 1;
-}
-
-int h2_stream_set_has_unsubmitted(h2_stream_set *sp)
-{
-    int has_unsubmitted = 0;
-    h2_stream_set_iter(sp, unsubmitted_iter, &has_unsubmitted);
-    return has_unsubmitted;
-}
-
-static int input_open_iter(void *ctx, h2_stream *stream)
-{
-    if (h2_stream_input_is_open(stream)) {
-        *((int *)ctx) = 1;
-        return 0;
-    }
-    return 1;
-}
-
-int h2_stream_set_has_open_input(h2_stream_set *sp)
-{
-    int has_input_open = 0;
-    h2_stream_set_iter(sp, input_open_iter, &has_input_open);
-    return has_input_open;
-}
-
-static int suspended_iter(void *ctx, h2_stream *stream)
-{
-    if (h2_stream_is_suspended(stream)) {
-        *((int *)ctx) = 1;
-        return 0;
-    }
-    return 1;
-}
-
-int h2_stream_set_has_suspended(h2_stream_set *sp)
-{
-    int has_suspended = 0;
-    h2_stream_set_iter(sp, suspended_iter, &has_suspended);
-    return has_suspended;
-}
-
diff --git a/modules/http2/h2_stream_set.h b/modules/http2/h2_stream_set.h
deleted file mode 100644 (file)
index d0041c4..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __mod_h2__h2_stream_set__
-#define __mod_h2__h2_stream_set__
-
-/**
- * A set of h2_stream instances. Allows lookup by stream id
- * and other criteria.
- */
-
-typedef h2_stream *h2_stream_set_match_fn(void *ctx, h2_stream *stream);
-typedef int h2_stream_set_iter_fn(void *ctx, h2_stream *stream);
-
-typedef struct h2_stream_set h2_stream_set;
-
-
-h2_stream_set *h2_stream_set_create(apr_pool_t *pool, int max);
-
-void h2_stream_set_destroy(h2_stream_set *sp);
-
-void h2_stream_set_add(h2_stream_set *sp, h2_stream *stream);
-
-h2_stream *h2_stream_set_get(h2_stream_set *sp, int stream_id);
-
-void h2_stream_set_remove(h2_stream_set *sp, int stream_id);
-
-void h2_stream_set_iter(h2_stream_set *sp,
-                        h2_stream_set_iter_fn *iter, void *ctx);
-
-int h2_stream_set_is_empty(h2_stream_set *sp);
-
-apr_size_t h2_stream_set_size(h2_stream_set *sp);
-
-int h2_stream_set_has_unsubmitted(h2_stream_set *sp);
-int h2_stream_set_has_open_input(h2_stream_set *sp);
-int h2_stream_set_has_suspended(h2_stream_set *sp);
-
-#endif /* defined(__mod_h2__h2_stream_set__) */
index b64683ab17c0e06aaac53ad3370f5694a83a9659..1cbe8d1e8e32c8a4dcfb4f2b3cd161b3811b4227 100644 (file)
@@ -231,6 +231,72 @@ const char *h2_util_first_token_match(apr_pool_t *pool, const char *s,
 }
 
 
+/*******************************************************************************
+ * ihash - hash for structs with int identifier
+ ******************************************************************************/
+struct h2_ihash_t {
+    apr_hash_t *hash;
+    size_t ioff;
+};
+
+static unsigned int ihash(const char *key, apr_ssize_t *klen)
+{
+    return (unsigned int)(*((int*)key));
+}
+
+h2_ihash_t *h2_ihash_create(apr_pool_t *pool, size_t offset_of_int)
+{
+    h2_ihash_t *ih = apr_pcalloc(pool, sizeof(h2_ihash_t));
+    ih->hash = apr_hash_make_custom(pool, ihash);
+    ih->ioff = offset_of_int;
+    return ih;
+}
+
+size_t h2_ihash_count(h2_ihash_t *ih)
+{
+    return apr_hash_count(ih->hash);
+}
+
+int h2_ihash_is_empty(h2_ihash_t *ih)
+{
+    return apr_hash_count(ih->hash) == 0;
+}
+
+void *h2_ihash_get(h2_ihash_t *ih, int id)
+{
+    return apr_hash_get(ih->hash, &id, sizeof(id));
+}
+
+typedef struct {
+    h2_ihash_iter_t *iter;
+    void *ctx;
+} iter_ctx;
+
+static int ihash_iter(void *ctx, const void *key, apr_ssize_t klen, 
+                     const void *val)
+{
+    iter_ctx *ictx = ctx;
+    return ictx->iter(ictx->ctx, (void*)val); /* why is this passed const?*/
+}
+
+void h2_ihash_iter(h2_ihash_t *ih, h2_ihash_iter_t *fn, void *ctx)
+{
+    iter_ctx ictx;
+    ictx.iter = fn;
+    ictx.ctx = ctx;
+    apr_hash_do(ihash_iter, &ictx, ih->hash);
+}
+
+void h2_ihash_add(h2_ihash_t *ih, void *val)
+{
+    apr_hash_set(ih->hash, ((char *)val + ih->ioff), sizeof(int), val);
+}
+
+void h2_ihash_remove(h2_ihash_t *ih, int id)
+{
+    apr_hash_set(ih->hash, &id, sizeof(id), NULL);
+}
+
 /*******************************************************************************
  * h2_util for apt_table_t
  ******************************************************************************/
index 218a57fddfed22bf3dc1d115f06efcf4cfd024a1..e13a0dc2f2a6ba7604e92ac94e66a6b75513b01d 100644 (file)
@@ -16,6 +16,9 @@
 #ifndef __mod_h2__h2_util__
 #define __mod_h2__h2_util__
 
+/*******************************************************************************
+ * some debugging/format helpers
+ ******************************************************************************/
 struct h2_request;
 struct nghttp2_frame;
 
@@ -30,6 +33,38 @@ void h2_util_camel_case_header(char *s, size_t len);
 
 int h2_util_frame_print(const nghttp2_frame *frame, char *buffer, size_t maxlen);
 
+/*******************************************************************************
+ * ihash - hash for structs with int identifier
+ ******************************************************************************/
+typedef struct h2_ihash_t h2_ihash_t;
+typedef int h2_ihash_iter_t(void *ctx, void *val);
+
+/**
+ * Create a hash for structures that have an identifying int member.
+ * @param pool the pool to use
+ * @param offset_of_int the offsetof() the int member in the struct
+ */
+h2_ihash_t *h2_ihash_create(apr_pool_t *pool, size_t offset_of_int);
+
+size_t h2_ihash_count(h2_ihash_t *ih);
+int h2_ihash_is_empty(h2_ihash_t *ih);
+void *h2_ihash_get(h2_ihash_t *ih, int id);
+
+/**
+ * Iterate over the hash members (without defined order) and invoke
+ * fn for each member until 0 is returned.
+ * @param ih the hash to iterate over
+ * @param fn the function to invoke on each member
+ * @param ctx user supplied data passed into each iteration call
+ */
+void h2_ihash_iter(h2_ihash_t *ih, h2_ihash_iter_t *fn, void *ctx);
+
+void h2_ihash_add(h2_ihash_t *ih, void *val);
+void h2_ihash_remove(h2_ihash_t *ih, int id);
+/*******************************************************************************
+ * common helpers
+ ******************************************************************************/
 /**
  * Count the bytes that all key/value pairs in a table have
  * in length (exlucding terminating 0s), plus additional extra per pair.
@@ -40,11 +75,6 @@ int h2_util_frame_print(const nghttp2_frame *frame, char *buffer, size_t maxlen)
  */
 apr_size_t h2_util_table_bytes(apr_table_t *t, apr_size_t pair_extra);
 
-int h2_req_ignore_header(const char *name, size_t len);
-int h2_req_ignore_trailer(const char *name, size_t len);
-int h2_res_ignore_trailer(const char *name, size_t len);
-int h2_proxy_res_ignore_header(const char *name, size_t len);
-
 /**
  * Return != 0 iff the string s contains the token, as specified in
  * HTTP header syntax, rfc7230.
@@ -54,6 +84,32 @@ int h2_util_contains_token(apr_pool_t *pool, const char *s, const char *token);
 const char *h2_util_first_token_match(apr_pool_t *pool, const char *s, 
                                       const char *tokens[], apr_size_t len);
 
+/** Match a header value against a string constance, case insensitive */
+#define H2_HD_MATCH_LIT(l, name, nlen)  \
+    ((nlen == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
+
+/*******************************************************************************
+ * HTTP/2 header helpers
+ ******************************************************************************/
+int h2_req_ignore_header(const char *name, size_t len);
+int h2_req_ignore_trailer(const char *name, size_t len);
+int h2_res_ignore_trailer(const char *name, size_t len);
+int h2_proxy_res_ignore_header(const char *name, size_t len);
+
+/**
+ * Set the push policy for the given request. Takes request headers into 
+ * account, see draft https://tools.ietf.org/html/draft-ruellan-http-accept-push-policy-00
+ * for details.
+ * 
+ * @param req the request to determine the policy for
+ * @param p the pool to use
+ * @param push_enabled if HTTP/2 server push is generally enabled for this request
+ */
+void h2_push_policy_determine(struct h2_request *req, apr_pool_t *p, int push_enabled);
+
+/*******************************************************************************
+ * base64 url encoding, different table from normal base64
+ ******************************************************************************/
 /**
  * I always wanted to write my own base64url decoder...not. See 
  * https://tools.ietf.org/html/rfc4648#section-5 for description.
@@ -64,8 +120,9 @@ apr_size_t h2_util_base64url_decode(const char **decoded,
 const char *h2_util_base64url_encode(const char *data, 
                                      apr_size_t len, apr_pool_t *pool);
 
-#define H2_HD_MATCH_LIT(l, name, nlen)  \
-    ((nlen == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
+/*******************************************************************************
+ * nghttp2 helpers
+ ******************************************************************************/
 
 #define H2_HD_MATCH_LIT_CS(l, name)  \
     ((strlen(name) == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
@@ -99,6 +156,9 @@ h2_ngheader *h2_util_ngheader_make_res(apr_pool_t *p,
 h2_ngheader *h2_util_ngheader_make_req(apr_pool_t *p, 
                                        const struct h2_request *req);
 
+/*******************************************************************************
+ * apr brigade helpers
+ ******************************************************************************/
 /**
  * Moves data from one brigade into another. If maxlen > 0, it only
  * moves up to maxlen bytes into the target brigade, making bucket splits
@@ -192,15 +252,4 @@ apr_status_t h2_transfer_brigade(apr_bucket_brigade *to,
                                  apr_off_t *plen,
                                  int *peos);
 
-/**
- * Set the push policy for the given request. Takes request headers into 
- * account, see draft https://tools.ietf.org/html/draft-ruellan-http-accept-push-policy-00
- * for details.
- * 
- * @param req the request to determine the policy for
- * @param p the pool to use
- * @param push_enabled if HTTP/2 server push is generally enabled for this request
- */
-void h2_push_policy_determine(struct h2_request *req, apr_pool_t *p, int push_enabled);
-
 #endif /* defined(__mod_h2__h2_util__) */
index 0431548a961a3e987e411392b2955c77146b6740..3bfb09d25759abc995a2641c003801110f8ec765 100644 (file)
@@ -177,10 +177,6 @@ SOURCE=./h2_stream.c
 # End Source File
 # Begin Source File
 
-SOURCE=./h2_stream_set.c
-# End Source File
-# Begin Source File
-
 SOURCE=./h2_switch.c
 # End Source File
 # Begin Source File
index 3cdf44ae74cb01556ea028b205e7d1cf01df4539..efd69465c29fd568decbe214e07a97328328c2d6 100644 (file)
@@ -233,11 +233,27 @@ static void request_done(h2_proxy_session *session, request_rec *r)
     }
 }
 
+static request_rec *next_request(h2_proxy_ctx *ctx, h2_proxy_session *session, 
+                                 request_rec *r)
+{
+    if (!r && !ctx->standalone) {
+        ctx->engine->capacity = session->remote_max_concurrent;
+        if (req_engine_pull(ctx->engine, APR_NONBLOCK_READ, &r) == APR_SUCCESS) {
+            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, 
+                          "h2_proxy_session(%s): pulled request %s", 
+                          session->id, r->the_request);
+        }
+    }
+    return r; 
+}
+
 static apr_status_t proxy_engine_run(h2_proxy_ctx *ctx, request_rec *r) {
     apr_status_t status = OK;
     h2_proxy_session *session;
     
-setup_session:    
+setup_backend:    
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->owner, 
+                  "eng(%s): setup backend", ctx->engine->id);
     /* Step Two: Make the Connection (or check that an already existing
      * socket is still usable). On success, we have a socket connected to
      * backend->hostname. */
@@ -280,6 +296,8 @@ setup_session:
     /* Step Four: Send the Request in a new HTTP/2 stream and
      * loop until we got the response or encounter errors.
      */
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->owner, 
+                  "eng(%s): setup session", ctx->engine->id);
     session = h2_proxy_session_setup(ctx->engine->id, ctx->p_conn, 
                                      ctx->conf, request_done);
     if (!session) {
@@ -289,39 +307,34 @@ setup_session:
     }
     
 run_session:
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->owner, 
+                  "eng(%s): run session %s", ctx->engine->id, session->id);
     session->user_data = ctx;
-    add_request(session, r);
-    status = APR_EAGAIN;
+    status = h2_proxy_session_process(session);
     while (APR_STATUS_IS_EAGAIN(status)) {
-        status = h2_proxy_session_process(session);
-        
-        if (APR_STATUS_IS_EAGAIN(status) && !ctx->standalone) {
-            ctx->engine->capacity = session->remote_max_concurrent;
-            if (req_engine_pull(ctx->engine, APR_NONBLOCK_READ, &r) == APR_SUCCESS) {
-                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, 
-                              "h2_proxy_session(%s): pulled request %s", 
-                              session->id, r->the_request);
-                add_request(session, r);
-            }
+        r = next_request(ctx, session, r);
+        if (r) {
+            add_request(session, r);
+            r = NULL;
         }
+        
+        status = h2_proxy_session_process(session);
     }
     
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, ctx->owner, 
+                  "eng(%s): end of session run", ctx->engine->id);
     if (session->state == H2_PROXYS_ST_DONE || status != APR_SUCCESS) {
         ctx->p_conn->close = 1;
     }
     
-    if (!ctx->standalone) { 
-        ctx->engine->capacity = session->remote_max_concurrent;
-        if (req_engine_pull(ctx->engine, APR_NONBLOCK_READ, &r) == APR_SUCCESS) {
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, 
-                          "h2_proxy_session(%s): idle, pulled request %s", 
-                          session->id, r->the_request);
-            add_request(session, r);
-            if (ctx->p_conn->close) {
-                goto setup_session;
-            }
-            goto run_session;
+    r = next_request(ctx, session, r);
+    if (r) { 
+        if (ctx->p_conn->close) {
+            goto setup_backend;
         }
+        add_request(session, r);
+        r = NULL;
+        goto run_session;
     }
 
     if (session->streams && !h2_iq_empty(session->streams)) {
@@ -330,8 +343,9 @@ run_session:
                       "session run done with %d streams unfinished",
                       h2_iq_size(session->streams));
     }
-    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, 
-                  ctx->p_conn->connection, "session run done");
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, 
+                  ctx->p_conn->connection, "eng(%s): session run done",
+                  ctx->engine->id);
     session->user_data = NULL;
     return status;
 }