httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ic...@apache.org
Subject svn commit: r1733259 [1/4] - in /httpd/httpd/branches/2.4.x: ./ modules/http2/
Date Wed, 02 Mar 2016 11:21:29 GMT
Author: icing
Date: Wed Mar  2 11:21:28 2016
New Revision: 1733259

URL: http://svn.apache.org/viewvc?rev=1733259&view=rev
Log:
backport of mod_http2 v1.3.2 minus event conn-status fixup

Added:
    httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2
    httpd/httpd/branches/2.4.x/modules/http2/config2.m4
    httpd/httpd/branches/2.4.x/modules/http2/h2.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.h
Removed:
    httpd/httpd/branches/2.4.x/modules/http2/config.m4
Modified:
    httpd/httpd/branches/2.4.x/CHANGES
    httpd/httpd/branches/2.4.x/CMakeLists.txt
    httpd/httpd/branches/2.4.x/modules/http2/NWGNUmakefile
    httpd/httpd/branches/2.4.x/modules/http2/h2_config.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_config.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_h2.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_h2.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_io.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_io.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_io_set.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_io_set.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_mplx.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_mplx.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_private.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_push.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_push.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_request.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_request.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_response.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_session.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_session.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_stream.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_stream.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_task.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_task.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_task_input.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_task_input.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_task_output.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_task_output.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_util.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_util.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_version.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_worker.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_worker.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_workers.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_workers.h
    httpd/httpd/branches/2.4.x/modules/http2/mod_http2.c
    httpd/httpd/branches/2.4.x/modules/http2/mod_http2.dsp
    httpd/httpd/branches/2.4.x/modules/http2/mod_http2.h

Modified: httpd/httpd/branches/2.4.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/CHANGES?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.4.x/CHANGES [utf-8] Wed Mar  2 11:21:28 2016
@@ -2,6 +2,60 @@
 
 Changes with Apache 2.4.19
 
+  *) mod_http2: Accept-Encoding is, when present on the initiating request, 
+     added to push promises. This lets compressed content work in pushes.
+     by the client. [Stefan Eissing]
+
+  *) mod_http2: fixed possible read after free when streams were cancelled early
+     by the client. [Stefan Eissing]
+
+  *) mod_http2: fixed possible deadlock during connection shutdown. Thanks to 
+     @FrankStolle for reporting and getting the necessary data.
+     [Stefan Eissing]
+
+  *) mod_http2: fixed apr_uint64_t formatting in a log statement to user proper 
+     APR def, thanks to @Sp1l.
+     
+  *) mod_http2: number of worker threads allowed to a connection is adjusting 
+     dynamically. Starting with 4, the number is doubled when streams can be 
+     served without block on http/2 connection flow. The number is halfed, when
+     the server has to wait on client flow control grants. 
+     This can happen with a maximum frequency of 5 times per second. 
+     When a connection occupies too many workers, repeatable requests 
+     (GET/HEAD/OPTIONS) are cancelled and placed back in the queue. Should that 
+     not suffice and a stream is busy longer than the server timeout, the 
+     connection will be aborted with error code ENHANCE_YOUR_CALM.
+     This does *not* limit the number of streams a client may open, rather the
+     number of server threads a connection might use.
+     [Stefan Eissing]
+  
+  *) mod_http2: allowing link header to specify multiple "rel" values, 
+     space-separated inside a quoted string. Prohibiting push when Link 
+     parameter "nopush" is present.
+     [Stefan Eissing]
+
+  *) mod_http2: reworked connection state handling. Idle connections accept a
+     GOAWAY from the client without further reply. Otherwise the
+     module makes a best effort to send one last GOAWAY to the client.
+     
+  *) mod_http2: the values from standard directives Timeout and KeepAliveTimeout
+     properly are applied to http/2 connections.
+     [Stefan Eissing]
+
+  *) mod_http2: idle connections are returned to async mpms. new hook
+     "pre_close_connection" used to send GOAWAY frame when not already done.
+     Setting event mpm server config "by hand" for the main connection to
+     the correct negotiated server.
+     [Stefan Eissing]
+
+  *) mod_http2: keep-alive blocking reads are done with 1 second timeouts to
+     check for MPM stopping. Will announce early GOAWAY and finish processing
+     open streams, then close.
+     [Stefan Eissing]
+
+  *) mod_http2: bytes read/written on slave connections are reported via the
+     optional mod_logio functions. Fixes PR 58871.
+
   *) mod_ssl: Add SSLOCSPProxyURL to add the possibility to do all queries
      to OCSP responders through a HTTP proxy. [Ruediger Pluem]
 
@@ -50,7 +104,7 @@ Changes with Apache 2.4.19
      be inherited by virtual hosts that define a CustomLog.
      [Edward Lu]
 
-  *) mod_http2: connection how keep a "push diary" where hashes of already
+  *) mod_http2: connections how keep a "push diary" where hashes of already
      pushed resources are kept. See directive H2PushDiarySize for managing this.
      Push diaries can be initialized by clients via the "Cache-Digest" request
      header. This carries a base64url encoded. compressed Golomb set as described
@@ -81,11 +135,6 @@ Changes with Apache 2.4.19
      when available for request.
      [Stefan Eissing]
 
-  *) mod_http2: new config directives and the implementation behind
-     them: H2Timeout, H2KeepAliveTimeout, H2StreamTimeout. Documentation in
-     the http2 manual.
-     [Stefan Eissing]
-
   *) mod_http2: fixed bug in input window size calculation by moving chunked
      request body encoding into later stage of processing. Fixes PR 58825.
      [Stefan Eissing]

Modified: httpd/httpd/branches/2.4.x/CMakeLists.txt
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/CMakeLists.txt?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/CMakeLists.txt (original)
+++ httpd/httpd/branches/2.4.x/CMakeLists.txt Wed Mar  2 11:21:28 2016
@@ -388,9 +388,9 @@ 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_task_queue.c
+  modules/http2/h2_task_output.c     modules/http2/h2_int_queue.c
   modules/http2/h2_util.c            modules/http2/h2_worker.c
   modules/http2/h2_workers.c
 )

Modified: httpd/httpd/branches/2.4.x/modules/http2/NWGNUmakefile
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/NWGNUmakefile?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/NWGNUmakefile (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/NWGNUmakefile Wed Mar  2 11:21:28 2016
@@ -1,9 +1,4 @@
 #
-# This Makefile requires the environment var NGH2SRC
-# pointing to the base directory of nghttp2 source tree.
-#
-
-#
 # Declare the sub-directories to be built here
 #
 
@@ -19,6 +14,7 @@ include $(AP_WORK)/build/NWGNUhead.inc
 
 #
 # build this level's files
+
 #
 # Make sure all needed macro's are defined
 #
@@ -28,13 +24,6 @@ include $(AP_WORK)/build/NWGNUhead.inc
 # INCDIRS
 #
 XINCDIRS	+= \
-			$(APR)/include \
-			$(APRUTIL)/include \
-			$(SRC)/include \
-			$(NGH2SRC)/lib/ \
-			$(NGH2SRC)/lib/includes \
-			$(SERVER)/mpm/NetWare \
-			$(NWOS) \
 			$(EOLIST)
 
 #
@@ -47,14 +36,12 @@ XCFLAGS		+= \
 # These defines will come after DEFINES
 #
 XDEFINES	+= \
-			-DHAVE_CONFIG_H \
 			$(EOLIST)
 
 #
 # These flags will be added to the link.opt file
 #
 XLFLAGS		+= \
-			-L$(OBJDIR) \
 			$(EOLIST)
 
 #
@@ -108,19 +95,19 @@ endif
 # This is used by the link 'name' directive to name the nlm.  If left blank
 # TARGET_nlm (see below) will be used.
 #
-NLM_NAME	= mod_http2
+NLM_NAME	=
 
 #
 # This is used by the link '-desc ' directive.
 # If left blank, NLM_NAME will be used.
 #
-NLM_DESCRIPTION	= Apache $(VERSION_STR) HTTP2 Support module (w/ NGHTTP2 Lib)
+NLM_DESCRIPTION	=
 
 #
 # This is used by the '-threadname' directive.  If left blank,
 # NLM_NAME Thread will be used.
 #
-NLM_THREAD_NAME	= $(NLM_NAME)
+NLM_THREAD_NAME	=
 
 #
 # If this is specified, it will override VERSION value in
@@ -131,7 +118,8 @@ NLM_VERSION	=
 #
 # If this is specified, it will override the default of 64K
 #
-NLM_STACK_SIZE	= 65536
+NLM_STACK_SIZE	=
+
 
 #
 # If this is specified it will be used by the link '-entry' directive
@@ -149,7 +137,7 @@ NLM_EXIT_SYM	=
 NLM_CHECK_SYM	=
 
 #
-# If this is specified it will be used by the link '-flags' directive
+# If these are specified it will be used by the link '-flags' directive
 #
 NLM_FLAGS	=
 
@@ -161,36 +149,31 @@ NLM_FLAGS	=
 XDCDATA		=
 
 #
-# Declare all target files (you must add your files here)
-#
-
-#
 # If there is an NLM target, put it here
 #
 TARGET_nlm = \
-	$(OBJDIR)/$(NLM_NAME).nlm \
+	$(OBJDIR)/mod_http2.nlm \
+	$(OBJDIR)/mod_http2.nlm \
 	$(EOLIST)
 
 #
 # If there is an LIB target, put it here
 #
 TARGET_lib = \
-	$(OBJDIR)/nghttp2.lib \
 	$(EOLIST)
 
 #
 # These are the OBJ files needed to create the NLM target above.
 # Paths must all use the '/' character
 #
-FILES_nlm_objs := $(sort $(patsubst %.c,$(OBJDIR)/%.o,$(wildcard *.c)))
+FILES_nlm_objs = \
+	$(EOLIST)
 
 #
 # These are the LIB files needed to create the NLM target above.
 # These will be added as a library command in the link.opt file.
 #
 FILES_nlm_libs = \
-	$(PRELUDE) \
-	$(OBJDIR)/nghttp2.lib \
 	$(EOLIST)
 
 #
@@ -198,8 +181,6 @@ FILES_nlm_libs = \
 # These will be added as a module command in the link.opt file.
 #
 FILES_nlm_modules = \
-	Libc \
-	Apache2 \
 	$(EOLIST)
 
 #
@@ -221,28 +202,26 @@ FILE_nlm_copyright =
 # Any additional imports go here
 #
 FILES_nlm_Ximports = \
-	@libc.imp \
-	@aprlib.imp \
-	@httpd.imp \
 	$(EOLIST)
 
 #
 # Any symbols exported to here
 #
 FILES_nlm_exports = \
-	http2_module \
 	$(EOLIST)
 
 #
 # These are the OBJ files needed to create the LIB target above.
 # Paths must all use the '/' character
 #
-FILES_lib_objs := $(sort $(patsubst $(NGH2SRC)/lib/%.c,$(OBJDIR)/%.o,$(wildcard $(NGH2SRC)/lib/*.c)))
+FILES_lib_objs = \
+	$(EOLIST)
+
 #
 # implement targets and dependancies (leave this section alone)
 #
 
-libs :: $(OBJDIR) $(NGH2SRC)/lib/config.h $(TARGET_lib)
+libs :: $(OBJDIR) $(TARGET_lib)
 
 nlms :: libs $(TARGET_nlm)
 
@@ -251,75 +230,11 @@ nlms :: libs $(TARGET_nlm)
 # correct place.  (See $(AP_WORK)/build/NWGNUhead.inc for examples)
 #
 install :: nlms FORCE
-	$(call COPY,$(OBJDIR)/*.nlm,        $(INSTALLBASE)/modules/)
+	$(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
 
-clean ::
-	$(call DEL,$(NGH2SRC)/lib/config.h)
 #
 # Any specialized rules here
 #
-vpath %.c $(NGH2SRC)/lib
-
-$(NGH2SRC)/lib/config.h : NWGNUmakefile
-	@echo $(DL)GEN  $@$(DL)
-	@echo $(DL)/* For NetWare target.$(DL) > $@
-	@echo $(DL)** Do not edit - created by Make!$(DL) >> $@
-	@echo $(DL)*/$(DL) >> $@
-	@echo $(DL)#ifndef NGH2_CONFIG_H$(DL) >> $@
-	@echo $(DL)#define NGH2_CONFIG_H$(DL) >> $@
-	@echo #define HAVE_ARPA_INET_H 1 >> $@
-	@echo #define HAVE_CHOWN 1 >> $@
-	@echo #define HAVE_DECL_STRERROR_R 1 >> $@
-	@echo #define HAVE_DLFCN_H 1 >> $@
-	@echo #define HAVE_DUP2 1 >> $@
-	@echo #define HAVE_FCNTL_H 1 >> $@
-	@echo #define HAVE_GETCWD 1 >> $@
-	@echo #define HAVE_INTTYPES_H 1 >> $@
-	@echo #define HAVE_LIMITS_H 1 >> $@
-	@echo #define HAVE_LOCALTIME_R 1 >> $@
-	@echo #define HAVE_MALLOC 1 >> $@
-	@echo #define HAVE_MEMCHR 1 >> $@
-	@echo #define HAVE_MEMMOVE 1 >> $@
-	@echo #define HAVE_MEMORY_H 1 >> $@
-	@echo #define HAVE_MEMSET 1 >> $@
-	@echo #define HAVE_NETDB_H 1 >> $@
-	@echo #define HAVE_NETINET_IN_H 1 >> $@
-	@echo #define HAVE_PTRDIFF_T 1 >> $@
-	@echo #define HAVE_PWD_H 1 >> $@
-	@echo #define HAVE_SOCKET 1 >> $@
-	@echo #define HAVE_SQRT 1 >> $@
-	@echo #define HAVE_STDDEF_H 1 >> $@
-	@echo #define HAVE_STDINT_H 1 >> $@
-	@echo #define HAVE_STDLIB_H 1 >> $@
-	@echo #define HAVE_STRCHR 1 >> $@
-	@echo #define HAVE_STRDUP 1 >> $@
-	@echo #define HAVE_STRERROR 1 >> $@
-	@echo #define HAVE_STRERROR_R 1 >> $@
-	@echo #define HAVE_STRINGS_H 1 >> $@
-	@echo #define HAVE_STRING_H 1 >> $@
-	@echo #define HAVE_STRSTR 1 >> $@
-	@echo #define HAVE_STRTOL 1 >> $@
-	@echo #define HAVE_STRTOUL 1 >> $@
-	@echo #define HAVE_SYSLOG_H 1 >> $@
-	@echo #define HAVE_SYS_SOCKET_H 1 >> $@
-	@echo #define HAVE_SYS_STAT_H 1 >> $@
-	@echo #define HAVE_SYS_TIME_H 1 >> $@
-	@echo #define HAVE_SYS_TYPES_H 1 >> $@
-	@echo #define HAVE_TIME_H 1 >> $@
-	@echo #define HAVE_UNISTD_H 1 >> $@
-
-	@echo #define SIZEOF_INT_P 4 >> $@
-	@echo #define STDC_HEADERS 1 >> $@
-	@echo #define STRERROR_R_CHAR_P 4 >> $@
-
-# Hint to compiler a function parameter is not used
-	@echo #define _U_ >> $@
-
-	@echo #ifndef __cplusplus >> $@
-	@echo #define inline __inline >> $@
-	@echo #endif >> $@
-
-	@echo $(DL)#endif /* NGH2_CONFIG_H */$(DL) >> $@
 
 #
 # Include the 'tail' makefile that has targets that depend on variables defined

Added: httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2?rev=1733259&view=auto
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2 (added)
+++ httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2 Wed Mar  2 11:21:28 2016
@@ -0,0 +1,360 @@
+#
+# This Makefile requires the environment var NGH2SRC
+# pointing to the base directory of nghttp2 source tree.
+#
+
+#
+# Declare the sub-directories to be built here
+#
+
+SUBDIRS = \
+	$(EOLIST)
+
+#
+# Get the 'head' of the build environment.  This includes default targets and
+# paths to tools
+#
+
+include $(AP_WORK)/build/NWGNUhead.inc
+
+#
+# build this level's files
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS	+= \
+			$(APR)/include \
+			$(APRUTIL)/include \
+			$(SRC)/include \
+			$(NGH2SRC)/lib/ \
+			$(NGH2SRC)/lib/includes \
+			$(SERVER)/mpm/NetWare \
+			$(STDMOD)/ssl \
+			$(NWOS) \
+			$(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS		+= \
+			$(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES	+= \
+			-DHAVE_CONFIG_H \
+			$(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS		+= \
+			-L$(OBJDIR) \
+			$(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS	+= \
+			$(EOLIST)
+
+XCFLAGS		+= \
+			$(EOLIST)
+
+XDEFINES	+= \
+			$(EOLIST)
+
+XLFLAGS		+= \
+			$(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS	+= \
+			$(EOLIST)
+
+XCFLAGS		+= \
+			$(EOLIST)
+
+XDEFINES	+= \
+			$(EOLIST)
+
+XLFLAGS		+= \
+			$(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS	+= \
+			$(EOLIST)
+
+XCFLAGS		+= \
+			$(EOLIST)
+
+XDEFINES	+= \
+			$(EOLIST)
+
+XLFLAGS		+= \
+			$(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm.  If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME	= mod_http2
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION	= Apache $(VERSION_STR) HTTP2 Support module (w/ NGHTTP2 Lib)
+
+#
+# This is used by the '-threadname' directive.  If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME	= $(NLM_NAME)
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION	=
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE	= 65536
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM	=
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM	=
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM	=
+
+#
+# If this is specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS	=
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc.  XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA		=
+
+#
+# Declare all target files (you must add your files here)
+#
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+	$(OBJDIR)/$(NLM_NAME).nlm \
+	$(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+	$(OBJDIR)/nghttp2.lib \
+	$(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+	$(OBJDIR)/h2_alt_svc.o \
+	$(OBJDIR)/h2_bucket_eoc.o \
+	$(OBJDIR)/h2_bucket_eos.o \
+	$(OBJDIR)/h2_config.o \
+	$(OBJDIR)/h2_conn.o \
+	$(OBJDIR)/h2_conn_io.o \
+	$(OBJDIR)/h2_ctx.o \
+	$(OBJDIR)/h2_filter.o \
+	$(OBJDIR)/h2_from_h1.o \
+	$(OBJDIR)/h2_h2.o \
+	$(OBJDIR)/h2_int_queue.o \
+	$(OBJDIR)/h2_io.o \
+	$(OBJDIR)/h2_io_set.o \
+	$(OBJDIR)/h2_mplx.o \
+	$(OBJDIR)/h2_push.o \
+	$(OBJDIR)/h2_request.o \
+	$(OBJDIR)/h2_response.o \
+	$(OBJDIR)/h2_session.o \
+	$(OBJDIR)/h2_stream.o \
+	$(OBJDIR)/h2_switch.o \
+	$(OBJDIR)/h2_task.o \
+	$(OBJDIR)/h2_task_input.o \
+	$(OBJDIR)/h2_task_output.o \
+	$(OBJDIR)/h2_util.o \
+	$(OBJDIR)/h2_worker.o \
+	$(OBJDIR)/h2_workers.o \
+	$(OBJDIR)/mod_http2.o \
+	$(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+	$(PRELUDE) \
+	$(OBJDIR)/nghttp2.lib \
+	$(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+	Libc \
+	Apache2 \
+	$(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+	@libc.imp \
+	@aprlib.imp \
+	@httpd.imp \
+	$(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+	http2_module \
+	$(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs := $(sort $(patsubst $(NGH2SRC)/lib/%.c,$(OBJDIR)/%.o,$(wildcard $(NGH2SRC)/lib/*.c)))
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(NGH2SRC)/lib/config.h $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place.  (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+	$(call COPY,$(OBJDIR)/*.nlm,        $(INSTALLBASE)/modules/)
+
+clean ::
+	$(call DEL,$(NGH2SRC)/lib/config.h)
+#
+# Any specialized rules here
+#
+vpath %.c $(NGH2SRC)/lib
+
+$(NGH2SRC)/lib/config.h : NWGNUmakefile
+	@echo $(DL)GEN  $@$(DL)
+	@echo $(DL)/* For NetWare target.$(DL) > $@
+	@echo $(DL)** Do not edit - created by Make!$(DL) >> $@
+	@echo $(DL)*/$(DL) >> $@
+	@echo $(DL)#ifndef NGH2_CONFIG_H$(DL) >> $@
+	@echo $(DL)#define NGH2_CONFIG_H$(DL) >> $@
+	@echo #define HAVE_ARPA_INET_H 1 >> $@
+	@echo #define HAVE_CHOWN 1 >> $@
+	@echo #define HAVE_DECL_STRERROR_R 1 >> $@
+	@echo #define HAVE_DLFCN_H 1 >> $@
+	@echo #define HAVE_DUP2 1 >> $@
+	@echo #define HAVE_FCNTL_H 1 >> $@
+	@echo #define HAVE_GETCWD 1 >> $@
+	@echo #define HAVE_INTTYPES_H 1 >> $@
+	@echo #define HAVE_LIMITS_H 1 >> $@
+	@echo #define HAVE_LOCALTIME_R 1 >> $@
+	@echo #define HAVE_MALLOC 1 >> $@
+	@echo #define HAVE_MEMCHR 1 >> $@
+	@echo #define HAVE_MEMMOVE 1 >> $@
+	@echo #define HAVE_MEMORY_H 1 >> $@
+	@echo #define HAVE_MEMSET 1 >> $@
+	@echo #define HAVE_NETDB_H 1 >> $@
+	@echo #define HAVE_NETINET_IN_H 1 >> $@
+	@echo #define HAVE_PTRDIFF_T 1 >> $@
+	@echo #define HAVE_PWD_H 1 >> $@
+	@echo #define HAVE_SOCKET 1 >> $@
+	@echo #define HAVE_SQRT 1 >> $@
+	@echo #define HAVE_STDDEF_H 1 >> $@
+	@echo #define HAVE_STDINT_H 1 >> $@
+	@echo #define HAVE_STDLIB_H 1 >> $@
+	@echo #define HAVE_STRCHR 1 >> $@
+	@echo #define HAVE_STRDUP 1 >> $@
+	@echo #define HAVE_STRERROR 1 >> $@
+	@echo #define HAVE_STRERROR_R 1 >> $@
+	@echo #define HAVE_STRINGS_H 1 >> $@
+	@echo #define HAVE_STRING_H 1 >> $@
+	@echo #define HAVE_STRSTR 1 >> $@
+	@echo #define HAVE_STRTOL 1 >> $@
+	@echo #define HAVE_STRTOUL 1 >> $@
+	@echo #define HAVE_SYSLOG_H 1 >> $@
+	@echo #define HAVE_SYS_SOCKET_H 1 >> $@
+	@echo #define HAVE_SYS_STAT_H 1 >> $@
+	@echo #define HAVE_SYS_TIME_H 1 >> $@
+	@echo #define HAVE_SYS_TYPES_H 1 >> $@
+	@echo #define HAVE_TIME_H 1 >> $@
+	@echo #define HAVE_UNISTD_H 1 >> $@
+
+	@echo #define SIZEOF_INT_P 4 >> $@
+	@echo #define STDC_HEADERS 1 >> $@
+	@echo #define STRERROR_R_CHAR_P 4 >> $@
+
+# Hint to compiler a function parameter is not used
+	@echo #define _U_ >> $@
+
+	@echo #ifndef __cplusplus >> $@
+	@echo #define inline __inline >> $@
+	@echo #endif >> $@
+
+	@echo $(DL)#endif /* NGH2_CONFIG_H */$(DL) >> $@
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+

Added: httpd/httpd/branches/2.4.x/modules/http2/config2.m4
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/config2.m4?rev=1733259&view=auto
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/config2.m4 (added)
+++ httpd/httpd/branches/2.4.x/modules/http2/config2.m4 Wed Mar  2 11:21:28 2016
@@ -0,0 +1,207 @@
+dnl Licensed to the Apache Software Foundation (ASF) under one or more
+dnl contributor license agreements.  See the NOTICE file distributed with
+dnl this work for additional information regarding copyright ownership.
+dnl The ASF licenses this file to You under the Apache License, Version 2.0
+dnl (the "License"); you may not use this file except in compliance with
+dnl the License.  You may obtain a copy of the License at
+dnl
+dnl      http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
+
+dnl #  start of module specific part
+APACHE_MODPATH_INIT(http2)
+
+dnl #  list of module object files
+http2_objs="dnl
+mod_http2.lo dnl
+h2_alt_svc.lo dnl
+h2_bucket_eoc.lo dnl
+h2_bucket_eos.lo dnl
+h2_config.lo dnl
+h2_conn.lo dnl
+h2_conn_io.lo dnl
+h2_ctx.lo dnl
+h2_filter.lo dnl
+h2_from_h1.lo dnl
+h2_h2.lo dnl
+h2_int_queue.lo dnl
+h2_io.lo dnl
+h2_io_set.lo dnl
+h2_mplx.lo dnl
+h2_push.lo dnl
+h2_request.lo dnl
+h2_response.lo dnl
+h2_session.lo dnl
+h2_stream.lo dnl
+h2_switch.lo dnl
+h2_task.lo dnl
+h2_task_input.lo dnl
+h2_task_output.lo dnl
+h2_util.lo dnl
+h2_worker.lo dnl
+h2_workers.lo dnl
+"
+
+dnl
+dnl APACHE_CHECK_NGHTTP2
+dnl
+dnl Configure for nghttp2, giving preference to
+dnl "--with-nghttp2=<path>" if it was specified.
+dnl
+AC_DEFUN([APACHE_CHECK_NGHTTP2],[
+  AC_CACHE_CHECK([for nghttp2], [ac_cv_nghttp2], [
+    dnl initialise the variables we use
+    ac_cv_nghttp2=no
+    ap_nghttp2_found=""
+    ap_nghttp2_base=""
+    ap_nghttp2_libs=""
+
+    dnl Determine the nghttp2 base directory, if any
+    AC_MSG_CHECKING([for user-provided nghttp2 base directory])
+    AC_ARG_WITH(nghttp2, APACHE_HELP_STRING(--with-nghttp2=PATH, nghttp2 installation directory), [
+      dnl If --with-nghttp2 specifies a directory, we use that directory
+      if test "x$withval" != "xyes" -a "x$withval" != "x"; then
+        dnl This ensures $withval is actually a directory and that it is absolute
+        ap_nghttp2_base="`cd $withval ; pwd`"
+      fi
+    ])
+    if test "x$ap_nghttp2_base" = "x"; then
+      AC_MSG_RESULT(none)
+    else
+      AC_MSG_RESULT($ap_nghttp2_base)
+    fi
+
+    dnl Run header and version checks
+    saved_CPPFLAGS="$CPPFLAGS"
+    saved_LIBS="$LIBS"
+    saved_LDFLAGS="$LDFLAGS"
+
+    dnl Before doing anything else, load in pkg-config variables
+    if test -n "$PKGCONFIG"; then
+      saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
+      AC_MSG_CHECKING([for pkg-config along $PKG_CONFIG_PATH])
+      if test "x$ap_nghttp2_base" != "x" -a \
+              -f "${ap_nghttp2_base}/lib/pkgconfig/libnghttp2.pc"; then
+        dnl Ensure that the given path is used by pkg-config too, otherwise
+        dnl the system libnghttp2.pc might be picked up instead.
+        PKG_CONFIG_PATH="${ap_nghttp2_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
+        export PKG_CONFIG_PATH
+      fi
+      AC_ARG_ENABLE(nghttp2-staticlib-deps,APACHE_HELP_STRING(--enable-nghttp2-staticlib-deps,[link mod_http2 with dependencies of libnghttp2's static libraries (as indicated by "pkg-config --static"). Must be specified in addition to --enable-http2.]), [
+        if test "$enableval" = "yes"; then
+          PKGCONFIG_LIBOPTS="--static"
+        fi
+      ])
+      ap_nghttp2_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors libnghttp2`"
+      if test $? -eq 0; then
+        ap_nghttp2_found="yes"
+        pkglookup="`$PKGCONFIG --cflags-only-I libnghttp2`"
+        APR_ADDTO(CPPFLAGS, [$pkglookup])
+        APR_ADDTO(MOD_CFLAGS, [$pkglookup])
+        APR_ADDTO(ab_CFLAGS, [$pkglookup])
+        pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L libnghttp2`"
+        APR_ADDTO(LDFLAGS, [$pkglookup])
+        APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
+        pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other libnghttp2`"
+        APR_ADDTO(LDFLAGS, [$pkglookup])
+        APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
+      fi
+      PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
+    fi
+
+    dnl fall back to the user-supplied directory if not found via pkg-config
+    if test "x$ap_nghttp2_base" != "x" -a "x$ap_nghttp2_found" = "x"; then
+      APR_ADDTO(CPPFLAGS, [-I$ap_nghttp2_base/include])
+      APR_ADDTO(MOD_CFLAGS, [-I$ap_nghttp2_base/include])
+      APR_ADDTO(ab_CFLAGS, [-I$ap_nghttp2_base/include])
+      APR_ADDTO(LDFLAGS, [-L$ap_nghttp2_base/lib])
+      APR_ADDTO(MOD_LDFLAGS, [-L$ap_nghttp2_base/lib])
+      if test "x$ap_platform_runtime_link_flag" != "x"; then
+        APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag$ap_nghttp2_base/lib])
+        APR_ADDTO(MOD_LDFLAGS, [$ap_platform_runtime_link_flag$ap_nghttp2_base/lib])
+      fi
+    fi
+
+    AC_MSG_CHECKING([for nghttp2 version >= 1.2.1])
+    AC_TRY_COMPILE([#include <nghttp2/nghttp2ver.h>],[
+#if !defined(NGHTTP2_VERSION_NUM)
+#error "Missing nghttp2 version"
+#endif
+#if NGHTTP2_VERSION_NUM < 0x010201
+#error "Unsupported nghttp2 version " NGHTTP2_VERSION_TEXT
+#endif],
+      [AC_MSG_RESULT(OK)
+       ac_cv_nghttp2=yes],
+      [AC_MSG_RESULT(FAILED)])
+
+    if test "x$ac_cv_nghttp2" = "xyes"; then
+      ap_nghttp2_libs="${ap_nghttp2_libs:--lnghttp2} `$apr_config --libs`"
+      APR_ADDTO(MOD_LDFLAGS, [$ap_nghttp2_libs])
+      APR_ADDTO(LIBS, [$ap_nghttp2_libs])
+      APR_SETVAR(ab_LDFLAGS, [$MOD_LDFLAGS])
+      APACHE_SUBST(ab_CFLAGS)
+      APACHE_SUBST(ab_LDFLAGS)
+
+      dnl Run library and function checks
+      liberrors=""
+      AC_CHECK_HEADERS([nghttp2/nghttp2.h])
+      AC_CHECK_FUNCS([nghttp2_session_server_new2], [], [liberrors="yes"])
+      if test "x$liberrors" != "x"; then
+        AC_MSG_WARN([nghttp2 library is unusable])
+      fi
+dnl # nghttp2 >= 1.3.0: access to stream weights
+      AC_CHECK_FUNCS([nghttp2_stream_get_weight], [], [liberrors="yes"])
+      if test "x$liberrors" != "x"; then
+        AC_MSG_WARN([nghttp2 version >= 1.3.0 is required])
+      fi
+dnl # nghttp2 >= 1.5.0: changing stream priorities
+      AC_CHECK_FUNCS([nghttp2_session_change_stream_priority], 
+        [APR_ADDTO(MOD_CPPFLAGS, ["-DH2_NG2_CHANGE_PRIO"])], [])
+    else
+      AC_MSG_WARN([nghttp2 version is too old])
+    fi
+
+    dnl restore
+    CPPFLAGS="$saved_CPPFLAGS"
+    LIBS="$saved_LIBS"
+    LDFLAGS="$saved_LDFLAGS"
+  ])
+  if test "x$ac_cv_nghttp2" = "xyes"; then
+    AC_DEFINE(HAVE_NGHTTP2, 1, [Define if nghttp2 is available])
+  fi
+])
+
+
+dnl # hook module into the Autoconf mechanism (--enable-http2)
+APACHE_MODULE(http2, [HTTP/2 protocol handling in addition to HTTP protocol 
+handling. Implemented by mod_http2. This module requires a libnghttp2 installation. 
+See --with-nghttp2 on how to manage non-standard locations. This module
+is usually linked shared and requires loading. ], $http2_objs, , most, [
+    APACHE_CHECK_OPENSSL
+    if test "$ac_cv_openssl" = "yes" ; then
+        APR_ADDTO(MOD_CPPFLAGS, ["-DH2_OPENSSL"])
+    fi
+
+    APACHE_CHECK_NGHTTP2
+    if test "$ac_cv_nghttp2" = "yes" ; then
+        if test "x$enable_http2" = "xshared"; then
+           # The only symbol which needs to be exported is the module
+           # structure, so ask libtool to hide everything else:
+           APR_ADDTO(MOD_HTTP2_LDADD, [-export-symbols-regex http2_module])
+        fi
+    else
+        enable_http2=no
+    fi
+])
+
+# Ensure that other modules can pick up mod_http2.h
+# APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
+
+dnl #  end of module specific part
+APACHE_MODPATH_FINISH
+

Added: httpd/httpd/branches/2.4.x/modules/http2/h2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2.h?rev=1733259&view=auto
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2.h (added)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2.h Wed Mar  2 11:21:28 2016
@@ -0,0 +1,142 @@
+/* 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__
+#define __mod_h2__h2__
+
+/**
+ * The magic PRIamble of RFC 7540 that is always sent when starting
+ * a h2 communication.
+ */
+extern const char *H2_MAGIC_TOKEN;
+
+#define H2_ERR_NO_ERROR             (0x00)
+#define H2_ERR_PROTOCOL_ERROR       (0x01)
+#define H2_ERR_INTERNAL_ERROR       (0x02)
+#define H2_ERR_FLOW_CONTROL_ERROR   (0x03)
+#define H2_ERR_SETTINGS_TIMEOUT     (0x04)
+#define H2_ERR_STREAM_CLOSED        (0x05)
+#define H2_ERR_FRAME_SIZE_ERROR     (0x06)
+#define H2_ERR_REFUSED_STREAM       (0x07)
+#define H2_ERR_CANCEL               (0x08)
+#define H2_ERR_COMPRESSION_ERROR    (0x09)
+#define H2_ERR_CONNECT_ERROR        (0x0a)
+#define H2_ERR_ENHANCE_YOUR_CALM    (0x0b)
+#define H2_ERR_INADEQUATE_SECURITY  (0x0c)
+#define H2_ERR_HTTP_1_1_REQUIRED    (0x0d)
+
+#define H2_HEADER_METHOD     ":method"
+#define H2_HEADER_METHOD_LEN 7
+#define H2_HEADER_SCHEME     ":scheme"
+#define H2_HEADER_SCHEME_LEN 7
+#define H2_HEADER_AUTH       ":authority"
+#define H2_HEADER_AUTH_LEN   10
+#define H2_HEADER_PATH       ":path"
+#define H2_HEADER_PATH_LEN   5
+#define H2_CRLF             "\r\n"
+
+/* Maximum number of padding bytes in a frame, rfc7540 */
+#define H2_MAX_PADLEN               256
+/* Initial default window size, RFC 7540 ch. 6.5.2 */
+#define H2_INITIAL_WINDOW_SIZE      ((64*1024)-1)
+
+#define H2_HTTP_2XX(a)      ((a) >= 200 && (a) < 300)
+
+#define H2_STREAM_CLIENT_INITIATED(id)      (id&0x01)
+
+#define H2_ALEN(a)          (sizeof(a)/sizeof((a)[0]))
+
+#define H2MAX(x,y) ((x) > (y) ? (x) : (y))
+#define H2MIN(x,y) ((x) < (y) ? (x) : (y))
+
+typedef enum {
+    H2_DEPENDANT_AFTER,
+    H2_DEPENDANT_INTERLEAVED,
+    H2_DEPENDANT_BEFORE,
+} h2_dependency;
+
+typedef struct h2_priority {
+    h2_dependency dependency;
+    int           weight;
+} h2_priority;
+
+typedef enum {
+    H2_PUSH_NONE,
+    H2_PUSH_DEFAULT,
+    H2_PUSH_HEAD,
+    H2_PUSH_FAST_LOAD,
+} h2_push_policy;
+
+typedef enum {
+    H2_STREAM_ST_IDLE,
+    H2_STREAM_ST_OPEN,
+    H2_STREAM_ST_RESV_LOCAL,
+    H2_STREAM_ST_RESV_REMOTE,
+    H2_STREAM_ST_CLOSED_INPUT,
+    H2_STREAM_ST_CLOSED_OUTPUT,
+    H2_STREAM_ST_CLOSED,
+} h2_stream_state_t;
+
+typedef enum {
+    H2_SESSION_ST_INIT,             /* send initial SETTINGS, etc. */
+    H2_SESSION_ST_DONE,             /* finished, connection close */
+    H2_SESSION_ST_IDLE,             /* nothing to write, expecting data inc */
+    H2_SESSION_ST_BUSY,             /* read/write without stop */
+    H2_SESSION_ST_WAIT,             /* waiting for tasks reporting back */
+    H2_SESSION_ST_LOCAL_SHUTDOWN,   /* we announced GOAWAY */
+    H2_SESSION_ST_REMOTE_SHUTDOWN,  /* client announced GOAWAY */
+} h2_session_state;
+
+/* h2_request is the transformer of HTTP2 streams into HTTP/1.1 internal
+ * format that will be fed to various httpd input filters to finally
+ * become a request_rec to be handled by soemone.
+ */
+typedef struct h2_request h2_request;
+
+struct h2_request {
+    int id;             /* stream id */
+
+    const char *method; /* pseudo header values, see ch. 8.1.2.3 */
+    const char *scheme;
+    const char *authority;
+    const char *path;
+    
+    apr_table_t *headers;
+    apr_table_t *trailers;
+
+    apr_time_t request_time;
+    apr_off_t content_length;
+    
+    unsigned int chunked : 1; /* iff requst body needs to be forwarded as chunked */
+    unsigned int eoh     : 1; /* iff end-of-headers has been seen and request is complete */
+    unsigned int body    : 1; /* iff this request has a body */
+    unsigned int serialize : 1; /* iff this request is written in HTTP/1.1 serialization */
+    unsigned int push_policy; /* which push policy to use for this request */
+};
+
+typedef struct h2_response h2_response;
+
+struct h2_response {
+    int         stream_id;
+    int         rst_error;
+    int         http_status;
+    apr_off_t   content_length;
+    apr_table_t *headers;
+    apr_table_t *trailers;
+    const char  *sos_filter;
+};
+
+
+#endif /* defined(__mod_h2__h2__) */

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_config.c?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_config.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_config.c Wed Mar  2 11:21:28 2016
@@ -28,6 +28,7 @@
 
 #include <apr_strings.h>
 
+#include "h2.h"
 #include "h2_alt_svc.h"
 #include "h2_ctx.h"
 #include "h2_conn.h"
@@ -59,9 +60,6 @@ static h2_config defconf = {
     1,                      /* TLS cooldown secs */
     1,                      /* HTTP/2 server push enabled */
     NULL,                   /* map of content-type to priorities */
-    -1,                     /* connection timeout */
-    -1,                     /* keepalive timeout */
-    0,                      /* stream timeout */
     256,                    /* push diary size */
     
 };
@@ -96,9 +94,6 @@ static void *h2_config_create(apr_pool_t
     conf->tls_cooldown_secs    = DEF_VAL;
     conf->h2_push              = DEF_VAL;
     conf->priorities           = NULL;
-    conf->h2_timeout           = DEF_VAL;
-    conf->h2_keepalive         = DEF_VAL;
-    conf->h2_stream_timeout    = DEF_VAL;
     conf->push_diary_size      = DEF_VAL;
     
     return conf;
@@ -145,9 +140,6 @@ void *h2_config_merge(apr_pool_t *pool,
     else {
         n->priorities       = add->priorities? add->priorities : base->priorities;
     }
-    n->h2_timeout           = H2_CONFIG_GET(add, base, h2_timeout);
-    n->h2_keepalive = H2_CONFIG_GET(add, base, h2_keepalive);
-    n->h2_stream_timeout    = H2_CONFIG_GET(add, base, h2_stream_timeout);
     n->push_diary_size      = H2_CONFIG_GET(add, base, push_diary_size);
     
     return n;
@@ -191,12 +183,6 @@ apr_int64_t h2_config_geti64(const h2_co
             return H2_CONFIG_GET(conf, &defconf, tls_cooldown_secs);
         case H2_CONF_PUSH:
             return H2_CONFIG_GET(conf, &defconf, h2_push);
-        case H2_CONF_TIMEOUT_SECS:
-            return H2_CONFIG_GET(conf, &defconf, h2_timeout);
-        case H2_CONF_KEEPALIVE_SECS:
-            return H2_CONFIG_GET(conf, &defconf, h2_keepalive);
-        case H2_CONF_STREAM_TIMEOUT_SECS:
-            return H2_CONFIG_GET(conf, &defconf, h2_stream_timeout);
         case H2_CONF_PUSH_DIARY_SIZE:
             return H2_CONFIG_GET(conf, &defconf, push_diary_size);
         default:
@@ -496,42 +482,6 @@ static const char *h2_conf_set_tls_coold
     return NULL;
 }
 
-static const char *h2_conf_set_timeout(cmd_parms *parms,
-                                       void *arg, const char *value)
-{
-    h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
-    (void)arg;
-    cfg->h2_timeout = (int)apr_atoi64(value);
-    if (cfg->h2_timeout < 0) {
-        return "value must be >= 0";
-    }
-    return NULL;
-}
-
-static const char *h2_conf_set_keepalive(cmd_parms *parms,
-                                                 void *arg, const char *value)
-{
-    h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
-    (void)arg;
-    cfg->h2_keepalive = (int)apr_atoi64(value);
-    if (cfg->h2_keepalive < 0) {
-        return "value must be >= 0";
-    }
-    return NULL;
-}
-
-static const char *h2_conf_set_stream_timeout(cmd_parms *parms,
-                                              void *arg, const char *value)
-{
-    h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
-    (void)arg;
-    cfg->h2_stream_timeout = (int)apr_atoi64(value);
-    if (cfg->h2_stream_timeout < 0) {
-        return "value must be >= 0";
-    }
-    return NULL;
-}
-
 static const char *h2_conf_set_push_diary_size(cmd_parms *parms,
                                                void *arg, const char *value)
 {
@@ -587,12 +537,6 @@ const command_rec h2_cmds[] = {
                   RSRC_CONF, "off to disable HTTP/2 server push"),
     AP_INIT_TAKE23("H2PushPriority", h2_conf_add_push_priority, NULL,
                   RSRC_CONF, "define priority of PUSHed resources per content type"),
-    AP_INIT_TAKE1("H2Timeout", h2_conf_set_timeout, NULL,
-                  RSRC_CONF, "read/write timeout (seconds) for HTTP/2 connections"),
-    AP_INIT_TAKE1("H2KeepAliveTimeout", h2_conf_set_keepalive, NULL,
-                  RSRC_CONF, "timeout (seconds) for idle HTTP/2 connections, no streams open"),
-    AP_INIT_TAKE1("H2StreamTimeout", h2_conf_set_stream_timeout, NULL,
-                  RSRC_CONF, "read/write timeout (seconds) for HTTP/2 streams"),
     AP_INIT_TAKE1("H2PushDiarySize", h2_conf_set_push_diary_size, NULL,
                   RSRC_CONF, "size of push diary"),
     AP_END_CMD

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_config.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_config.h?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_config.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_config.h Wed Mar  2 11:21:28 2016
@@ -39,9 +39,6 @@ typedef enum {
     H2_CONF_TLS_WARMUP_SIZE,
     H2_CONF_TLS_COOLDOWN_SECS,
     H2_CONF_PUSH,
-    H2_CONF_TIMEOUT_SECS,
-    H2_CONF_KEEPALIVE_SECS,
-    H2_CONF_STREAM_TIMEOUT_SECS,
     H2_CONF_PUSH_DIARY_SIZE,
 } h2_config_var_t;
 
@@ -70,9 +67,6 @@ typedef struct h2_config {
     int h2_push;                  /* if HTTP/2 server push is enabled */
     struct apr_hash_t *priorities;/* map of content-type to h2_priority records */
     
-    int h2_timeout;               /* timeout for http/2 connections */
-    int h2_keepalive;             /* timeout for idle connections, no streams */
-    int h2_stream_timeout;        /* timeout for http/2 streams, slave connections */
     int push_diary_size;          /* # of entries in push diary */
 } h2_config;
 

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c Wed Mar  2 11:21:28 2016
@@ -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"
@@ -45,6 +44,7 @@ static struct h2_workers *workers;
 static h2_mpm_type_t mpm_type = H2_MPM_UNKNOWN;
 static module *mpm_module;
 static int async_mpm;
+static apr_socket_t *dummy_socket;
 
 static void check_modules(int force) 
 {
@@ -60,8 +60,13 @@ static void check_modules(int force)
                 mpm_module = m;
                 break;
             }
-            else if (!strcmp("worker.c", m->name)) {
-                mpm_type = H2_MPM_WORKER;
+            else if (!strcmp("motorz.c", m->name)) {
+                mpm_type = H2_MPM_MOTORZ;
+                mpm_module = m;
+                break;
+            }
+            else if (!strcmp("mpm_netware.c", m->name)) {
+                mpm_type = H2_MPM_NETWARE;
                 mpm_module = m;
                 break;
             }
@@ -70,6 +75,21 @@ static void check_modules(int force)
                 mpm_module = m;
                 break;
             }
+            else if (!strcmp("simple_api.c", m->name)) {
+                mpm_type = H2_MPM_SIMPLE;
+                mpm_module = m;
+                break;
+            }
+            else if (!strcmp("mpm_winnt.c", m->name)) {
+                mpm_type = H2_MPM_WINNT;
+                mpm_module = m;
+                break;
+            }
+            else if (!strcmp("worker.c", m->name)) {
+                mpm_type = H2_MPM_WORKER;
+                mpm_module = m;
+                break;
+            }
         }
         checked = 1;
     }
@@ -89,7 +109,6 @@ apr_status_t h2_conn_child_init(apr_pool
     
     status = ap_mpm_query(AP_MPMQ_IS_ASYNC, &async_mpm);
     if (status != APR_SUCCESS) {
-        ap_log_error(APLOG_MARK, APLOG_TRACE1, status, s, "querying MPM for async");
         /* some MPMs do not implemnent this */
         async_mpm = 0;
         status = APR_SUCCESS;
@@ -135,6 +154,13 @@ apr_status_t h2_conn_child_init(apr_pool
     ap_register_input_filter("H2_IN", h2_filter_core_input,
                              NULL, AP_FTYPE_CONNECTION);
    
+    status = h2_mplx_child_init(pool, s);
+
+    if (status == APR_SUCCESS) {
+        status = apr_socket_create(&dummy_socket, APR_INET, SOCK_STREAM,
+                                   APR_PROTO_TCP, pool);
+    }
+
     return status;
 }
 
@@ -168,6 +194,7 @@ apr_status_t h2_conn_setup(h2_ctx *ctx,
     }
 
     h2_ctx_session_set(ctx, session);
+    
     return APR_SUCCESS;
 }
 
@@ -182,9 +209,6 @@ apr_status_t h2_conn_run(struct h2_ctx *
         }
         status = h2_session_process(h2_ctx_session_get(ctx), async_mpm);
         
-        if (c->cs) {
-            c->cs->state = CONN_STATE_WRITE_COMPLETION;
-        }
         if (APR_STATUS_IS_EOF(status)) {
             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c, APLOGNO(03045)
                           "h2_session(%ld): process, closing conn", c->id);
@@ -204,74 +228,15 @@ apr_status_t h2_conn_run(struct h2_ctx *
     return DONE;
 }
 
-
-static void fix_event_conn(conn_rec *c, conn_rec *master);
-
-conn_rec *h2_slave_create(conn_rec *master, apr_pool_t *p, 
-                          apr_thread_t *thread, apr_socket_t *socket)
+apr_status_t h2_conn_pre_close(struct h2_ctx *ctx, conn_rec *c)
 {
-    conn_rec *c;
-    
-    AP_DEBUG_ASSERT(master);
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, master,
-                  "h2_conn(%ld): created from master", master->id);
-    
-    /* This is like the slave connection creation from 2.5-DEV. A
-     * very efficient way - not sure how compatible this is, since
-     * the core hooks are no longer run.
-     * But maybe it's is better this way, not sure yet.
-     */
-    c = (conn_rec *) apr_palloc(p, sizeof(conn_rec));
-    if (c == NULL) {
-        ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, master, 
-                      APLOGNO(02913) "h2_task: creating conn");
-        return NULL;
-    }
-    
-    memcpy(c, master, sizeof(conn_rec));
-           
-    /* Replace these */
-    c->id                     = (master->id & (long)p);
-    c->master                 = master;
-    c->pool                   = p;        
-    c->current_thread         = thread;
-    c->conn_config            = ap_create_conn_config(p);
-    c->notes                  = apr_table_make(p, 5);
-    c->input_filters          = NULL;
-    c->output_filters         = NULL;
-    c->bucket_alloc           = apr_bucket_alloc_create(p);
-    c->cs                     = NULL;
-    c->data_in_input_filters  = 0;
-    c->data_in_output_filters = 0;
-    c->clogging_input_filters = 1;
-    c->log                    = NULL;
-    c->log_id                 = NULL;
-    
-    /* TODO: these should be unique to this thread */
-    c->sbh                    = master->sbh;
-    
-    /* Simulate that we had already a request on this connection. */
-    c->keepalives             = 1;
-    
-    ap_set_module_config(c->conn_config, &core_module, socket);
+    apr_status_t status;
     
-    /* This works for mpm_worker so far. Other mpm modules have 
-     * different needs, unfortunately. The most interesting one 
-     * being mpm_event...
-     */
-    switch (h2_conn_mpm_type()) {
-        case H2_MPM_WORKER:
-            /* all fine */
-            break;
-        case H2_MPM_EVENT: 
-            fix_event_conn(c, master);
-            break;
-        default:
-            /* fingers crossed */
-            break;
+    status = h2_session_pre_close(h2_ctx_session_get(ctx), async_mpm);
+    if (status == APR_SUCCESS) {
+        return DONE; /* This is the same, right? */
     }
-    
-    return c;
+    return status;
 }
 
 /* This is an internal mpm event.c struct which is disguised
@@ -327,3 +292,89 @@ static void fix_event_conn(conn_rec *c,
     c->cs = &(cs->pub);
 }
 
+conn_rec *h2_slave_create(conn_rec *master, apr_pool_t *parent,
+                          apr_allocator_t *allocator)
+{
+    apr_pool_t *pool;
+    conn_rec *c;
+    void *cfg;
+    
+    AP_DEBUG_ASSERT(master);
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, master,
+                  "h2_conn(%ld): create slave", master->id);
+    
+    /* We create a pool with its own allocator to be used for
+     * processing a request. This is the only way to have the processing
+     * independant of its parent pool in the sense that it can work in
+     * another thread.
+     */
+    if (!allocator) {
+        apr_allocator_create(&allocator);
+    }
+    apr_pool_create_ex(&pool, parent, NULL, allocator);
+    apr_pool_tag(pool, "h2_slave_conn");
+    apr_allocator_owner_set(allocator, parent);
+    
+    c = (conn_rec *) apr_palloc(pool, sizeof(conn_rec));
+    if (c == NULL) {
+        ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, master, 
+                      APLOGNO(02913) "h2_task: creating conn");
+        return NULL;
+    }
+    
+    memcpy(c, master, sizeof(conn_rec));
+           
+    /* Replace these */
+    c->master                 = master;
+    c->pool                   = pool;   
+    c->conn_config            = ap_create_conn_config(pool);
+    c->notes                  = apr_table_make(pool, 5);
+    c->input_filters          = NULL;
+    c->output_filters         = NULL;
+    c->bucket_alloc           = apr_bucket_alloc_create(pool);
+    c->data_in_input_filters  = 0;
+    c->data_in_output_filters = 0;
+    c->clogging_input_filters = 1;
+    c->log                    = NULL;
+    c->log_id                 = NULL;
+    /* Simulate that we had already a request on this connection. */
+    c->keepalives             = 1;
+    /* We cannot install the master connection socket on the slaves, as
+     * modules mess with timeouts/blocking of the socket, with
+     * unwanted side effects to the master connection processing.
+     * Fortunately, since we never use the slave socket, we can just install
+     * a single, process-wide dummy and everyone is happy.
+     */
+    ap_set_module_config(c->conn_config, &core_module, dummy_socket);
+    /* TODO: these should be unique to this thread */
+    c->sbh                    = master->sbh;
+    /* TODO: not all mpm modules have learned about slave connections yet.
+     * copy their config from master to slave.
+     */
+    if (h2_conn_mpm_module()) {
+        cfg = ap_get_module_config(master->conn_config, h2_conn_mpm_module());
+        ap_set_module_config(c->conn_config, h2_conn_mpm_module(), cfg);
+    }
+
+    switch (h2_conn_mpm_type()) {
+        case H2_MPM_EVENT: 
+            fix_event_conn(c, master);
+            break;
+        default:
+            break;
+    }
+    
+    return c;
+}
+
+void h2_slave_destroy(conn_rec *slave, apr_allocator_t **pallocator)
+{
+    apr_allocator_t *allocator = apr_pool_allocator_get(slave->pool);
+    apr_pool_destroy(slave->pool);
+    if (pallocator) {
+        *pallocator = allocator;
+    }
+    else {
+        apr_allocator_destroy(allocator);
+    }
+}

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h Wed Mar  2 11:21:28 2016
@@ -38,6 +38,12 @@ apr_status_t h2_conn_setup(struct h2_ctx
  */
 apr_status_t h2_conn_run(struct h2_ctx *ctx, conn_rec *c);
 
+/**
+ * The connection is about to close. If we have not send a GOAWAY
+ * yet, this is the last chance.
+ */
+apr_status_t h2_conn_pre_close(struct h2_ctx *ctx, conn_rec *c);
+
 /* Initialize this child process for h2 connection work,
  * to be called once during child init before multi processing
  * starts.
@@ -50,13 +56,18 @@ typedef enum {
     H2_MPM_WORKER,
     H2_MPM_EVENT,
     H2_MPM_PREFORK,
+    H2_MPM_MOTORZ,
+    H2_MPM_SIMPLE,
+    H2_MPM_NETWARE,
+    H2_MPM_WINNT,
 } h2_mpm_type_t;
 
 /* Returns the type of MPM module detected */
 h2_mpm_type_t h2_conn_mpm_type(void);
 
 
-conn_rec *h2_slave_create(conn_rec *master, apr_pool_t *p, 
-                          apr_thread_t *thread, apr_socket_t *socket);
+conn_rec *h2_slave_create(conn_rec *master, apr_pool_t *parent,
+                          apr_allocator_t *allocator);
+void h2_slave_destroy(conn_rec *slave, apr_allocator_t **pallocator);
 
 #endif /* defined(__mod_h2__h2_conn__) */

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c Wed Mar  2 11:21:28 2016
@@ -44,7 +44,7 @@
  */
 #define WRITE_SIZE_MAX        (TLS_DATA_MAX - 100) 
 
-#define WRITE_BUFFER_SIZE     (8*WRITE_SIZE_MAX)
+#define WRITE_BUFFER_SIZE     (5*WRITE_SIZE_MAX)
 
 apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c, 
                              const h2_config *cfg, 
@@ -109,7 +109,7 @@ static apr_status_t pass_out(apr_bucket_
         return APR_SUCCESS;
     }
     
-    ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, NULL);
+    ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_WRITE, c);
     status = apr_brigade_length(bb, 0, &bblen);
     if (status == APR_SUCCESS) {
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03044)
@@ -171,90 +171,15 @@ static apr_status_t bucketeer_buffer(h2_
     return APR_SUCCESS;
 }
 
-apr_status_t h2_conn_io_write(h2_conn_io *io, 
-                              const char *buf, size_t length)
-{
-    apr_status_t status = APR_SUCCESS;
-    pass_out_ctx ctx;
-    
-    ctx.c = io->connection;
-    ctx.io = io;
-    io->unflushed = 1;
-    if (io->bufsize > 0) {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, io->connection,
-                      "h2_conn_io: buffering %ld bytes", (long)length);
-                      
-        if (!APR_BRIGADE_EMPTY(io->output)) {
-            status = h2_conn_io_pass(io);
-            io->unflushed = 1;
-        }
-        
-        while (length > 0 && (status == APR_SUCCESS)) {
-            apr_size_t avail = io->bufsize - io->buflen;
-            if (avail <= 0) {
-                
-                bucketeer_buffer(io);
-                status = pass_out(io->output, &ctx);
-                io->buflen = 0;
-            }
-            else if (length > avail) {
-                memcpy(io->buffer + io->buflen, buf, avail);
-                io->buflen += avail;
-                length -= avail;
-                buf += avail;
-            }
-            else {
-                memcpy(io->buffer + io->buflen, buf, length);
-                io->buflen += length;
-                length = 0;
-                break;
-            }
-        }
-        
-    }
-    else {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, status, io->connection,
-                      "h2_conn_io: writing %ld bytes to brigade", (long)length);
-        status = apr_brigade_write(io->output, pass_out, &ctx, buf, length);
-    }
-    
-    return status;
-}
-
 apr_status_t h2_conn_io_writeb(h2_conn_io *io, apr_bucket *b)
 {
     APR_BRIGADE_INSERT_TAIL(io->output, b);
-    io->unflushed = 1;
     return APR_SUCCESS;
 }
 
-apr_status_t h2_conn_io_consider_flush(h2_conn_io *io)
-{
-    apr_status_t status = APR_SUCCESS;
-    
-    /* The HTTP/1.1 network output buffer/flush behaviour does not
-     * give optimal performance in the HTTP/2 case, as the pattern of
-     * buckets (data/eor/eos) is different.
-     * As long as we have not found out the "best" way to deal with
-     * this, force a flush at least every WRITE_BUFFER_SIZE amount
-     * of data.
-     */
-    if (io->unflushed) {
-        apr_off_t len = 0;
-        if (!APR_BRIGADE_EMPTY(io->output)) {
-            apr_brigade_length(io->output, 0, &len);
-        }
-        len += io->buflen;
-        if (len >= WRITE_BUFFER_SIZE) {
-            return h2_conn_io_pass(io);
-        }
-    }
-    return status;
-}
-
 static apr_status_t h2_conn_io_flush_int(h2_conn_io *io, int force, int eoc)
 {
-    if (io->unflushed || force) {
+    if (io->buflen > 0 || !APR_BRIGADE_EMPTY(io->output)) {
         pass_out_ctx ctx;
         
         if (io->buflen > 0) {
@@ -262,7 +187,6 @@ static apr_status_t h2_conn_io_flush_int
             ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, io->connection,
                           "h2_conn_io: flush, flushing %ld bytes", (long)io->buflen);
             bucketeer_buffer(io);
-            io->buflen = 0;
         }
         
         if (force) {
@@ -273,10 +197,10 @@ static apr_status_t h2_conn_io_flush_int
         ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, io->connection,
                       "h2_conn_io: flush");
         /* Send it out */
-        io->unflushed = 0;
-        
+        io->buflen = 0;
         ctx.c = io->connection;
         ctx.io = eoc? NULL : io;
+        
         return pass_out(io->output, &ctx);
         /* no more access after this, as we might have flushed an EOC bucket
          * that de-allocated us all. */
@@ -284,19 +208,76 @@ static apr_status_t h2_conn_io_flush_int
     return APR_SUCCESS;
 }
 
-apr_status_t h2_conn_io_write_eoc(h2_conn_io *io, apr_bucket *b)
+apr_status_t h2_conn_io_pass(h2_conn_io *io, int flush)
 {
-    APR_BRIGADE_INSERT_TAIL(io->output, b);
-    return h2_conn_io_flush_int(io, 1, 1);
+    return h2_conn_io_flush_int(io, flush, 0);
 }
 
-apr_status_t h2_conn_io_flush(h2_conn_io *io)
+apr_status_t h2_conn_io_consider_pass(h2_conn_io *io)
 {
-    return h2_conn_io_flush_int(io, 1, 0);
+    apr_off_t len = 0;
+    
+    if (!APR_BRIGADE_EMPTY(io->output)) {
+        apr_brigade_length(io->output, 0, &len);
+    }
+    len += io->buflen;
+    if (len >= WRITE_BUFFER_SIZE) {
+        return h2_conn_io_pass(io, 0);
+    }
+    return APR_SUCCESS;
 }
 
-apr_status_t h2_conn_io_pass(h2_conn_io *io)
+apr_status_t h2_conn_io_write_eoc(h2_conn_io *io, h2_session *session)
+{
+    apr_bucket *b = h2_bucket_eoc_create(io->connection->bucket_alloc, session);
+    APR_BRIGADE_INSERT_TAIL(io->output, b);
+    b = apr_bucket_flush_create(io->connection->bucket_alloc);
+    APR_BRIGADE_INSERT_TAIL(io->output, b);
+    return h2_conn_io_flush_int(io, 0, 1);
+}
+
+apr_status_t h2_conn_io_write(h2_conn_io *io, 
+                              const char *buf, size_t length)
 {
-    return h2_conn_io_flush_int(io, 0, 0);
+    apr_status_t status = APR_SUCCESS;
+    pass_out_ctx ctx;
+    
+    ctx.c = io->connection;
+    ctx.io = io;
+    if (io->bufsize > 0) {
+        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, io->connection,
+                      "h2_conn_io: buffering %ld bytes", (long)length);
+                      
+        if (!APR_BRIGADE_EMPTY(io->output)) {
+            status = h2_conn_io_pass(io, 0);
+        }
+        
+        while (length > 0 && (status == APR_SUCCESS)) {
+            apr_size_t avail = io->bufsize - io->buflen;
+            if (avail <= 0) {
+                h2_conn_io_pass(io, 0);
+            }
+            else if (length > avail) {
+                memcpy(io->buffer + io->buflen, buf, avail);
+                io->buflen += avail;
+                length -= avail;
+                buf += avail;
+            }
+            else {
+                memcpy(io->buffer + io->buflen, buf, length);
+                io->buflen += length;
+                length = 0;
+                break;
+            }
+        }
+        
+    }
+    else {
+        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, status, io->connection,
+                      "h2_conn_io: writing %ld bytes to brigade", (long)length);
+        status = apr_brigade_write(io->output, pass_out, &ctx, buf, length);
+    }
+    
+    return status;
 }
 

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.h?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.h Wed Mar  2 11:21:28 2016
@@ -42,7 +42,6 @@ typedef struct {
     char *buffer;
     apr_size_t buflen;
     apr_size_t bufsize;
-    int unflushed;
 } h2_conn_io;
 
 apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c, 
@@ -51,16 +50,40 @@ apr_status_t h2_conn_io_init(h2_conn_io
 
 int h2_conn_io_is_buffered(h2_conn_io *io);
 
+/**
+ * Append data to the buffered output.
+ * @param buf the data to append
+ * @param length the length of the data to append
+ */
 apr_status_t h2_conn_io_write(h2_conn_io *io,
                          const char *buf,
                          size_t length);
-                         
-apr_status_t h2_conn_io_writeb(h2_conn_io *io, apr_bucket *b);
 
-apr_status_t h2_conn_io_consider_flush(h2_conn_io *io);
+/**
+ * Append a bucket to the buffered output.
+ * @param io the connection io
+ * @param b the bucket to append
+ */
+apr_status_t h2_conn_io_writeb(h2_conn_io *io, apr_bucket *b);
 
-apr_status_t h2_conn_io_pass(h2_conn_io *io);
-apr_status_t h2_conn_io_flush(h2_conn_io *io);
-apr_status_t h2_conn_io_write_eoc(h2_conn_io *io, apr_bucket *b);
+/**
+ * Append an End-Of-Connection bucket to the output that, once destroyed,
+ * will tear down the complete http2 session.
+ */
+apr_status_t h2_conn_io_write_eoc(h2_conn_io *io, struct h2_session *session);
+
+/**
+ * Pass any buffered data on to the connection output filters.
+ * @param io the connection io
+ * @param flush if a flush bucket should be appended to any output
+ */
+apr_status_t h2_conn_io_pass(h2_conn_io *io, int flush);
+
+/**
+ * Check the amount of buffered output and pass it on if enough has accumulated.
+ * @param io the connection io
+ * @param flush if a flush bucket should be appended to any output
+ */
+apr_status_t h2_conn_io_consider_pass(h2_conn_io *io);
 
 #endif /* defined(__mod_h2__h2_conn_io__) */

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.c?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.c Wed Mar  2 11:21:28 2016
@@ -101,7 +101,17 @@ int h2_ctx_is_task(h2_ctx *ctx)
     return ctx && ctx->task;
 }
 
-struct h2_task *h2_ctx_get_task(h2_ctx *ctx)
+h2_task *h2_ctx_get_task(h2_ctx *ctx)
 {
     return ctx? ctx->task : NULL;
 }
+
+h2_task *h2_ctx_cget_task(conn_rec *c)
+{
+    return h2_ctx_get_task(h2_ctx_get(c, 0));
+}
+
+h2_task *h2_ctx_rget_task(request_rec *r)
+{
+    return h2_ctx_get_task(h2_ctx_rget(r));
+}

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.h?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_ctx.h Wed Mar  2 11:21:28 2016
@@ -71,5 +71,7 @@ const char *h2_ctx_protocol_get(const co
 int h2_ctx_is_task(h2_ctx *ctx);
 
 struct h2_task *h2_ctx_get_task(h2_ctx *ctx);
+struct h2_task *h2_ctx_cget_task(conn_rec *c);
+struct h2_task *h2_ctx_rget_task(request_rec *r);
 
 #endif /* defined(__mod_h2__h2_ctx__) */

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c Wed Mar  2 11:21:28 2016
@@ -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"
@@ -92,9 +91,9 @@ h2_filter_cin *h2_filter_cin_create(apr_
     return cin;
 }
 
-void h2_filter_cin_timeout_set(h2_filter_cin *cin, int timeout_secs)
+void h2_filter_cin_timeout_set(h2_filter_cin *cin, apr_interval_time_t timeout)
 {
-    cin->timeout_secs = timeout_secs;
+    cin->timeout = timeout;
 }
 
 apr_status_t h2_filter_core_input(ap_filter_t* f,
@@ -105,12 +104,12 @@ apr_status_t h2_filter_core_input(ap_fil
 {
     h2_filter_cin *cin = f->ctx;
     apr_status_t status = APR_SUCCESS;
-    apr_time_t saved_timeout = UNSET;
+    apr_interval_time_t saved_timeout = UNSET;
     
     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
-                  "core_input(%ld): read, %s, mode=%d, readbytes=%ld, timeout=%d", 
+                  "core_input(%ld): read, %s, mode=%d, readbytes=%ld", 
                   (long)f->c->id, (block == APR_BLOCK_READ)? "BLOCK_READ" : "NONBLOCK_READ", 
-                  mode, (long)readbytes, cin->timeout_secs);
+                  mode, (long)readbytes);
     
     if (mode == AP_MODE_INIT || mode == AP_MODE_SPECULATIVE) {
         return ap_get_brigade(f->next, brigade, mode, block, readbytes);
@@ -137,10 +136,9 @@ apr_status_t h2_filter_core_input(ap_fil
          * in the scoreboard is preserved.
          */
         if (block == APR_BLOCK_READ) {
-            if (cin->timeout_secs > 0) {
-                apr_time_t t = apr_time_from_sec(cin->timeout_secs);
+            if (cin->timeout > 0) {
                 apr_socket_timeout_get(cin->socket, &saved_timeout);
-                apr_socket_timeout_set(cin->socket, t);
+                apr_socket_timeout_set(cin->socket, cin->timeout);
             }
         }
         status = ap_get_brigade(f->next, cin->bb, AP_MODE_READBYTES,
@@ -148,8 +146,6 @@ apr_status_t h2_filter_core_input(ap_fil
         if (saved_timeout != UNSET) {
             apr_socket_timeout_set(cin->socket, saved_timeout);
         }
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c,
-                      "core_input(%ld): got_brigade", (long)f->c->id);
     }
     
     switch (status) {
@@ -159,6 +155,8 @@ apr_status_t h2_filter_core_input(ap_fil
         case APR_EOF:
         case APR_EAGAIN:
         case APR_TIMEUP:
+            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c,
+                          "core_input(%ld): read", (long)f->c->id);
             break;
         default:
             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, f->c, APLOGNO(03046)
@@ -218,7 +216,7 @@ static apr_status_t h2_sos_h2_status_buf
     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);

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h Wed Mar  2 11:21:28 2016
@@ -29,13 +29,13 @@ typedef struct h2_filter_cin {
     h2_filter_cin_cb *cb;
     void *cb_ctx;
     apr_socket_t *socket;
-    int timeout_secs;
+    apr_interval_time_t timeout;
     apr_time_t start_read;
 } h2_filter_cin;
 
 h2_filter_cin *h2_filter_cin_create(apr_pool_t *p, h2_filter_cin_cb *cb, void *ctx);
 
-void h2_filter_cin_timeout_set(h2_filter_cin *cin, int timeout_secs);
+void h2_filter_cin_timeout_set(h2_filter_cin *cin, apr_interval_time_t timeout);
 
 apr_status_t h2_filter_core_input(ap_filter_t* filter,
                                   apr_bucket_brigade* brigade,

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c Wed Mar  2 11:21:28 2016
@@ -49,12 +49,6 @@ h2_from_h1 *h2_from_h1_create(int stream
     return from_h1;
 }
 
-apr_status_t h2_from_h1_destroy(h2_from_h1 *from_h1)
-{
-    from_h1->bb = NULL;
-    return APR_SUCCESS;
-}
-
 static void set_state(h2_from_h1 *from_h1, h2_from_h1_state_t state)
 {
     if (from_h1->state != state) {

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.h?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.h Wed Mar  2 11:21:28 2016
@@ -60,8 +60,6 @@ struct h2_from_h1 {
 
 h2_from_h1 *h2_from_h1_create(int stream_id, apr_pool_t *pool);
 
-apr_status_t h2_from_h1_destroy(h2_from_h1 *response);
-
 apr_status_t h2_from_h1_read_response(h2_from_h1 *from_h1,
                                       ap_filter_t* f, apr_bucket_brigade* bb);
 

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_h2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_h2.c?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_h2.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_h2.c Wed Mar  2 11:21:28 2016
@@ -27,6 +27,8 @@
 #include <http_request.h>
 #include <http_log.h>
 
+#include "mod_ssl.h"
+
 #include "mod_http2.h"
 #include "h2_private.h"
 
@@ -54,21 +56,9 @@ const char *H2_MAGIC_TOKEN = "PRI * HTTP
 /*******************************************************************************
  * The optional mod_ssl functions we need. 
  */
-APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec*));
-APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec*));
-
-static int (*opt_ssl_engine_disable)(conn_rec*);
-static int (*opt_ssl_is_https)(conn_rec*);
-/*******************************************************************************
- * SSL var lookup
- */
-APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
-                        (apr_pool_t *, server_rec *,
-                         conn_rec *, request_rec *,
-                         char *));
-static char *(*opt_ssl_var_lookup)(apr_pool_t *, server_rec *,
-                                   conn_rec *, request_rec *,
-                                   char *);
+static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *opt_ssl_engine_disable;
+static APR_OPTIONAL_FN_TYPE(ssl_is_https) *opt_ssl_is_https;
+static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *opt_ssl_var_lookup;
 
 
 /*******************************************************************************
@@ -441,6 +431,7 @@ static int cipher_is_blacklisted(const c
  * - process_conn take over connection in case of h2
  */
 static int h2_h2_process_conn(conn_rec* c);
+static int h2_h2_pre_close_conn(conn_rec* c);
 static int h2_h2_post_read_req(request_rec *r);
 
 /*******************************************************************************
@@ -565,7 +556,11 @@ void h2_h2_register_hooks(void)
      */
     ap_hook_process_connection(h2_h2_process_conn, 
                                mod_ssl, mod_reqtimeout, APR_HOOK_LAST);
-                               
+    
+    /* One last chance to properly say goodbye if we have not done so
+     * already. */
+    ap_hook_pre_close_connection(h2_h2_pre_close_conn, NULL, mod_ssl, APR_HOOK_LAST);
+
     /* With "H2SerializeHeaders On", we install the filter in this hook
      * that parses the response. This needs to happen before any other post
      * read function terminates the request with an error. Otherwise we will
@@ -658,6 +653,25 @@ int h2_h2_process_conn(conn_rec* c)
     return DECLINED;
 }
 
+static int h2_h2_pre_close_conn(conn_rec *c)
+{
+    h2_ctx *ctx;
+
+    /* slave connection? */
+    if (c->master) {
+        return DECLINED;
+    }
+
+    ctx = h2_ctx_get(c, 0);
+    if (ctx) {
+        /* If the session has been closed correctly already, we will not
+         * fiond a h2_ctx here. The presence indicates that the session
+         * is still ongoing. */
+        return h2_conn_pre_close(ctx, c);
+    }
+    return DECLINED;
+}
+
 static int h2_h2_post_read_req(request_rec *r)
 {
     /* slave connection? */

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_h2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_h2.h?rev=1733259&r1=1733258&r2=1733259&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_h2.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_h2.h Wed Mar  2 11:21:28 2016
@@ -29,47 +29,6 @@ extern const char *h2_clear_protos[];
 extern const char *h2_tls_protos[];
 
 /**
- * The magic PRIamble of RFC 7540 that is always sent when starting
- * a h2 communication.
- */
-extern const char *H2_MAGIC_TOKEN;
-
-#define H2_ERR_NO_ERROR             (0x00)
-#define H2_ERR_PROTOCOL_ERROR       (0x01)
-#define H2_ERR_INTERNAL_ERROR       (0x02)
-#define H2_ERR_FLOW_CONTROL_ERROR   (0x03)
-#define H2_ERR_SETTINGS_TIMEOUT     (0x04)
-#define H2_ERR_STREAM_CLOSED        (0x05)
-#define H2_ERR_FRAME_SIZE_ERROR     (0x06)
-#define H2_ERR_REFUSED_STREAM       (0x07)
-#define H2_ERR_CANCEL               (0x08)
-#define H2_ERR_COMPRESSION_ERROR    (0x09)
-#define H2_ERR_CONNECT_ERROR        (0x0a)
-#define H2_ERR_ENHANCE_YOUR_CALM    (0x0b)
-#define H2_ERR_INADEQUATE_SECURITY  (0x0c)
-#define H2_ERR_HTTP_1_1_REQUIRED    (0x0d)
-
-/* Maximum number of padding bytes in a frame, rfc7540 */
-#define H2_MAX_PADLEN               256
-/* Initial default window size, RFC 7540 ch. 6.5.2 */
-#define H2_INITIAL_WINDOW_SIZE      ((64*1024)-1)
-
-#define H2_HTTP_2XX(a)      ((a) >= 200 && (a) < 300)
-
-#define H2_STREAM_CLIENT_INITIATED(id)      (id&0x01)
-
-typedef enum {
-    H2_DEPENDANT_AFTER,
-    H2_DEPENDANT_INTERLEAVED,
-    H2_DEPENDANT_BEFORE,
-} h2_dependency;
-
-typedef struct h2_priority {
-    h2_dependency dependency;
-    int           weight;
-} h2_priority;
-
-/**
  * Provide a user readable description of the HTTP/2 error code-
  * @param h2_error http/2 error code, as in rfc 7540, ch. 7
  * @return textual description of code or that it is unknown.

Added: httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.c?rev=1733259&view=auto
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.c (added)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.c Wed Mar  2 11:21:28 2016
@@ -0,0 +1,187 @@
+/* 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_pools.h>
+
+#include "h2_int_queue.h"
+
+
+static void tq_grow(h2_int_queue *q, int nlen);
+static void tq_swap(h2_int_queue *q, int i, int j);
+static int tq_bubble_up(h2_int_queue *q, int i, int top, 
+                        h2_iq_cmp *cmp, void *ctx);
+static int tq_bubble_down(h2_int_queue *q, int i, int bottom, 
+                          h2_iq_cmp *cmp, void *ctx);
+
+h2_int_queue *h2_iq_create(apr_pool_t *pool, int capacity)
+{
+    h2_int_queue *q = apr_pcalloc(pool, sizeof(h2_int_queue));
+    if (q) {
+        q->pool = pool;
+        tq_grow(q, capacity);
+        q->nelts = 0;
+    }
+    return q;
+}
+
+int h2_iq_empty(h2_int_queue *q)
+{
+    return q->nelts == 0;
+}
+
+int h2_iq_size(h2_int_queue *q)
+{
+    return q->nelts;
+}
+
+
+void h2_iq_add(h2_int_queue *q, int sid, h2_iq_cmp *cmp, void *ctx)
+{
+    int i;
+    
+    if (q->nelts >= q->nalloc) {
+        tq_grow(q, q->nalloc * 2);
+    }
+    
+    i = (q->head + q->nelts) % q->nalloc;
+    q->elts[i] = sid;
+    ++q->nelts;
+    
+    if (cmp) {
+        /* bubble it to the front of the queue */
+        tq_bubble_up(q, i, q->head, cmp, ctx);
+    }
+}
+
+int h2_iq_remove(h2_int_queue *q, int sid)
+{
+    int i;
+    for (i = 0; i < q->nelts; ++i) {
+        if (sid == q->elts[(q->head + i) % q->nalloc]) {
+            break;
+        }
+    }
+    
+    if (i < q->nelts) {
+        ++i;
+        for (; i < q->nelts; ++i) {
+            q->elts[(q->head+i-1)%q->nalloc] = q->elts[(q->head+i)%q->nalloc];
+        }
+        --q->nelts;
+        return 1;
+    }
+    return 0;
+}
+
+void h2_iq_clear(h2_int_queue *q)
+{
+    q->nelts = 0;
+}
+
+void h2_iq_sort(h2_int_queue *q, h2_iq_cmp *cmp, void *ctx)
+{
+    /* Assume that changes in ordering are minimal. This needs,
+     * best case, q->nelts - 1 comparisions to check that nothing
+     * changed.
+     */
+    if (q->nelts > 0) {
+        int i, ni, prev, last;
+        
+        /* Start at the end of the queue and create a tail of sorted
+         * entries. Make that tail one element longer in each iteration.
+         */
+        last = i = (q->head + q->nelts - 1) % q->nalloc;
+        while (i != q->head) {
+            prev = (q->nalloc + i - 1) % q->nalloc;
+            
+            ni = tq_bubble_up(q, i, prev, cmp, ctx);
+            if (ni == prev) {
+                /* i bubbled one up, bubble the new i down, which
+                 * keeps all tasks below i sorted. */
+                tq_bubble_down(q, i, last, cmp, ctx);
+            }
+            i = prev;
+        };
+    }
+}
+
+
+int h2_iq_shift(h2_int_queue *q)
+{
+    int sid;
+    
+    if (q->nelts <= 0) {
+        return 0;
+    }
+    
+    sid = q->elts[q->head];
+    q->head = (q->head + 1) % q->nalloc;
+    q->nelts--;
+    
+    return sid;
+}
+
+static void tq_grow(h2_int_queue *q, int nlen)
+{
+    if (nlen > q->nalloc) {
+        int *nq = apr_pcalloc(q->pool, sizeof(int) * nlen);
+        if (q->nelts > 0) {
+            int l = ((q->head + q->nelts) % q->nalloc) - q->head;
+            
+            memmove(nq, q->elts + q->head, sizeof(int) * l);
+            if (l < q->nelts) {
+                /* elts wrapped, append elts in [0, remain] to nq */
+                int remain = q->nelts - l;
+                memmove(nq + l, q->elts, sizeof(int) * remain);
+            }
+        }
+        q->elts = nq;
+        q->nalloc = nlen;
+        q->head = 0;
+    }
+}
+
+static void tq_swap(h2_int_queue *q, int i, int j)
+{
+    int x = q->elts[i];
+    q->elts[i] = q->elts[j];
+    q->elts[j] = x;
+}
+
+static int tq_bubble_up(h2_int_queue *q, int i, int top, 
+                        h2_iq_cmp *cmp, void *ctx) 
+{
+    int prev;
+    while (((prev = (q->nalloc + i - 1) % q->nalloc), i != top) 
+           && (*cmp)(q->elts[i], q->elts[prev], ctx) < 0) {
+        tq_swap(q, prev, i);
+        i = prev;
+    }
+    return i;
+}
+
+static int tq_bubble_down(h2_int_queue *q, int i, int bottom, 
+                          h2_iq_cmp *cmp, void *ctx)
+{
+    int next;
+    while (((next = (q->nalloc + i + 1) % q->nalloc), i != bottom) 
+           && (*cmp)(q->elts[i], q->elts[next], ctx) > 0) {
+        tq_swap(q, next, i);
+        i = next;
+    }
+    return i;
+}

Added: httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.h?rev=1733259&view=auto
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.h (added)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_int_queue.h Wed Mar  2 11:21:28 2016
@@ -0,0 +1,108 @@
+/* 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_int_queue__
+#define __mod_h2__h2_int_queue__
+
+/**
+ * h2_int_queue keeps a list of sorted h2_task* in ascending order.
+ */
+typedef struct h2_int_queue h2_int_queue;
+
+struct h2_int_queue {
+    int *elts;
+    int head;
+    int nelts;
+    int nalloc;
+    apr_pool_t *pool;
+};
+
+/**
+ * Comparator for two task to determine their order.
+ *
+ * @param s1 stream id to compare
+ * @param s2 stream id to compare
+ * @param ctx provided user data
+ * @return value is the same as for strcmp() and has the effect:
+ *    == 0: s1 and s2 are treated equal in ordering
+ *     < 0: s1 should be sorted before s2
+ *     > 0: s2 should be sorted before s1
+ */
+typedef int h2_iq_cmp(int s1, int s2, void *ctx);
+
+
+/**
+ * Allocate a new queue from the pool and initialize.
+ * @param id the identifier of the queue
+ * @param pool the memory pool
+ */
+h2_int_queue *h2_iq_create(apr_pool_t *pool, int capacity);
+
+/**
+ * Return != 0 iff there are no tasks in the queue.
+ * @param q the queue to check
+ */
+int h2_iq_empty(h2_int_queue *q);
+
+/**
+ * Return the number of int in the queue.
+ * @param q the queue to get size on
+ */
+int h2_iq_size(h2_int_queue *q);
+
+/**
+ * Add a stream idto the queue. 
+ *
+ * @param q the queue to append the task to
+ * @param sid the stream id to add
+ * @param cmp the comparator for sorting
+ * @param ctx user data for comparator 
+ */
+void h2_iq_add(h2_int_queue *q, int sid, h2_iq_cmp *cmp, void *ctx);
+
+/**
+ * Remove the stream id from the queue. Return != 0 iff task
+ * was found in queue.
+ * @param q the task queue
+ * @param sid the stream id to remove
+ * @return != 0 iff task was found in queue
+ */
+int h2_iq_remove(h2_int_queue *q, int sid);
+
+/**
+ * Remove all entries in the queue.
+ */
+void h2_iq_clear(h2_int_queue *q);
+
+/**
+ * Sort the stream idqueue again. Call if the task ordering
+ * has changed.
+ *
+ * @param q the queue to sort
+ * @param cmp the comparator for sorting
+ * @param ctx user data for the comparator 
+ */
+void h2_iq_sort(h2_int_queue *q, h2_iq_cmp *cmp, void *ctx);
+
+/**
+ * Get the first stream id from the queue or NULL if the queue is empty. 
+ * The task will be removed.
+ *
+ * @param q the queue to get the first task from
+ * @return the first stream id of the queue, 0 if empty
+ */
+int h2_iq_shift(h2_int_queue *q);
+
+#endif /* defined(__mod_h2__h2_int_queue__) */



Mime
View raw message