Index: modules/http2/h2_session.c
===================================================================
--- modules/http2/h2_session.c	(revision 1784618)
+++ modules/http2/h2_session.c	(working copy)
@@ -702,6 +702,12 @@
     ap_assert(session->ngh2);
     nghttp2_session_del(session->ngh2);
     session->ngh2 = NULL;
+    
+    if (session->allocator_mutex) {
+        apr_allocator_t *allocator = apr_pool_allocator_get(session->c->pool);
+        apr_allocator_mutex_set(allocator, NULL);
+        session->allocator_mutex = NULL;
+    }
 
     return APR_SUCCESS;
 }
@@ -718,125 +724,136 @@
     uint32_t n;
     apr_pool_t *pool = NULL;
     h2_session *session;
+    apr_status_t status;
+    int rv;
     
-    apr_status_t status = apr_allocator_create(&allocator);
-    if (status != APR_SUCCESS) {
-        return NULL;
-    }
-    apr_allocator_max_free_set(allocator, ap_max_mem_free);
-    apr_pool_create_ex(&pool, c->pool, NULL, allocator);
+    apr_pool_create(&pool, c->pool);
     if (!pool) {
-        apr_allocator_destroy(allocator);
         return NULL;
     }
     apr_pool_tag(pool, "h2_session");
-    apr_allocator_owner_set(allocator, pool);
-    status = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, pool);
-    if (status != APR_SUCCESS) {
+    
+    /* get h2_session a lifetime beyond its pool and everything
+     * connected to it. */
+    session = apr_pcalloc(pool, sizeof(h2_session));
+    if (!session) {
         apr_pool_destroy(pool);
         return NULL;
     }
-    apr_allocator_mutex_set(allocator, mutex);
     
-    /* get h2_session a lifetime beyond its pool and everything
-     * connected to it. */
-    session = apr_pcalloc(pool, sizeof(h2_session));
-    if (session) {
-        int rv;
-        session->id = c->id;
-        session->c = c;
-        session->r = r;
-        session->s = h2_ctx_server_get(ctx);
-        session->pool = pool;
-        session->config = h2_config_sget(session->s);
-        session->workers = workers;
-        
-        session->state = H2_SESSION_ST_INIT;
-        session->local.accepting = 1;
-        session->remote.accepting = 1;
-        
-        apr_pool_pre_cleanup_register(pool, session, session_pool_cleanup);
-        
-        session->max_stream_count = h2_config_geti(session->config, 
-                                                   H2_CONF_MAX_STREAMS);
-        session->max_stream_mem = h2_config_geti(session->config, 
-                                                 H2_CONF_STREAM_MAX_MEM);
-
-        status = apr_thread_cond_create(&session->iowait, session->pool);
+    session->id = c->id;
+    session->c = c;
+    session->r = r;
+    session->s = h2_ctx_server_get(ctx);
+    session->pool = pool;
+    session->config = h2_config_sget(session->s);
+    session->workers = workers;
+    
+    session->state = H2_SESSION_ST_INIT;
+    session->local.accepting = 1;
+    session->remote.accepting = 1;
+    
+    apr_pool_pre_cleanup_register(pool, session, session_pool_cleanup);
+    /* normally, connection pool allocators work without a mutex. However
+     * for http/2 connections, more multi-threading is going on and a mutex
+     * seems to be necessary. Set one, if it is missing. */
+    allocator = apr_pool_allocator_get(c->pool);
+    mutex = apr_allocator_mutex_get(allocator);
+    if (mutex == NULL) {
+        status = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, pool);
         if (status != APR_SUCCESS) {
+            apr_pool_destroy(pool);
             return NULL;
         }
-        
-        session->monitor = apr_pcalloc(pool, sizeof(h2_stream_monitor));
-        if (session->monitor == NULL) {
-            return NULL;
-        }
-        session->monitor->ctx = session;
-        session->monitor->on_state_enter = on_stream_state_enter;
-        session->monitor->on_state_event = on_stream_state_event;
-         
-        session->mplx = h2_mplx_create(c, session->pool, session->config, 
-                                       session->s->timeout, workers);
-        
-        h2_mplx_set_consumed_cb(session->mplx, update_window, session);
-        
-        /* Install the connection input filter that feeds the session */
-        session->cin = h2_filter_cin_create(session->pool, 
-                                            h2_session_receive, session);
-        ap_add_input_filter("H2_IN", session->cin, r, c);
-
-        h2_conn_io_init(&session->io, c, session->config);
-        session->bbtmp = apr_brigade_create(session->pool, c->bucket_alloc);
-        
-        status = init_callbacks(c, &callbacks);
-        if (status != APR_SUCCESS) {
-            ap_log_cerror(APLOG_MARK, APLOG_ERR, status, c, APLOGNO(02927) 
-                          "nghttp2: error in init_callbacks");
-            return NULL;
-        }
-        
-        rv = nghttp2_option_new(&options);
-        if (rv != 0) {
-            ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, c,
-                          APLOGNO(02928) "nghttp2_option_new: %s", 
-                          nghttp2_strerror(rv));
-            return NULL;
-        }
-        nghttp2_option_set_peer_max_concurrent_streams(
-            options, (uint32_t)session->max_stream_count);
-        /* We need to handle window updates ourself, otherwise we
-         * get flooded by nghttp2. */
-        nghttp2_option_set_no_auto_window_update(options, 1);
-        
-        rv = nghttp2_session_server_new2(&session->ngh2, callbacks,
-                                         session, options);
-        nghttp2_session_callbacks_del(callbacks);
-        nghttp2_option_del(options);
-        
-        if (rv != 0) {
-            ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, c,
-                          APLOGNO(02929) "nghttp2_session_server_new: %s",
-                          nghttp2_strerror(rv));
-            return NULL;
-        }
-        
-        n = h2_config_geti(session->config, H2_CONF_PUSH_DIARY_SIZE);
-        session->push_diary = h2_push_diary_create(session->pool, n);
-        
-        if (APLOGcdebug(c)) {
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, 
-                          H2_SSSN_LOG(APLOGNO(03200), session, 
-                          "created, max_streams=%d, stream_mem=%d, "
-                          "workers_limit=%d, workers_max=%d, "
-                          "push_diary(type=%d,N=%d)"),
-                          (int)session->max_stream_count, 
-                          (int)session->max_stream_mem,
-                          session->mplx->workers_limit, 
-                          session->mplx->workers_max, 
-                          session->push_diary->dtype, 
-                          (int)session->push_diary->N);
-        }
+        apr_allocator_mutex_set(allocator, mutex);
+        /* need to remember unsetting on pool clearance */
+        session->allocator_mutex = mutex; 
     }
+    
+    session->max_stream_count = h2_config_geti(session->config, 
+                                               H2_CONF_MAX_STREAMS);
+    session->max_stream_mem = h2_config_geti(session->config, 
+                                             H2_CONF_STREAM_MAX_MEM);
+    
+    status = apr_thread_cond_create(&session->iowait, session->pool);
+    if (status != APR_SUCCESS) {
+        apr_pool_destroy(pool);
+        return NULL;
+    }
+    
+    session->monitor = apr_pcalloc(pool, sizeof(h2_stream_monitor));
+    if (session->monitor == NULL) {
+        apr_pool_destroy(pool);
+        return NULL;
+    }
+    session->monitor->ctx = session;
+    session->monitor->on_state_enter = on_stream_state_enter;
+    session->monitor->on_state_event = on_stream_state_event;
+    
+    session->mplx = h2_mplx_create(c, session->pool, session->config, 
+                                   session->s->timeout, workers);
+    
+    h2_mplx_set_consumed_cb(session->mplx, update_window, session);
+    
+    /* Install the connection input filter that feeds the session */
+    session->cin = h2_filter_cin_create(session->pool, 
+                                        h2_session_receive, session);
+    ap_add_input_filter("H2_IN", session->cin, r, c);
+    
+    h2_conn_io_init(&session->io, c, session->config);
+    session->bbtmp = apr_brigade_create(session->pool, c->bucket_alloc);
+    
+    status = init_callbacks(c, &callbacks);
+    if (status != APR_SUCCESS) {
+        ap_log_cerror(APLOG_MARK, APLOG_ERR, status, c, APLOGNO(02927) 
+                      "nghttp2: error in init_callbacks");
+        apr_pool_destroy(pool);
+        return NULL;
+    }
+    
+    rv = nghttp2_option_new(&options);
+    if (rv != 0) {
+        ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, c,
+                      APLOGNO(02928) "nghttp2_option_new: %s", 
+                      nghttp2_strerror(rv));
+        apr_pool_destroy(pool);
+        return NULL;
+    }
+    nghttp2_option_set_peer_max_concurrent_streams(
+                                                   options, (uint32_t)session->max_stream_count);
+    /* We need to handle window updates ourself, otherwise we
+     * get flooded by nghttp2. */
+    nghttp2_option_set_no_auto_window_update(options, 1);
+    
+    rv = nghttp2_session_server_new2(&session->ngh2, callbacks,
+                                     session, options);
+    nghttp2_session_callbacks_del(callbacks);
+    nghttp2_option_del(options);
+    
+    if (rv != 0) {
+        ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, c,
+                      APLOGNO(02929) "nghttp2_session_server_new: %s",
+                      nghttp2_strerror(rv));
+        apr_pool_destroy(pool);
+        return NULL;
+    }
+    
+    n = h2_config_geti(session->config, H2_CONF_PUSH_DIARY_SIZE);
+    session->push_diary = h2_push_diary_create(session->pool, n);
+    
+    if (APLOGcdebug(c)) {
+        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, 
+                      H2_SSSN_LOG(APLOGNO(03200), session, 
+                                  "created, max_streams=%d, stream_mem=%d, "
+                                  "workers_limit=%d, workers_max=%d, "
+                                  "push_diary(type=%d,N=%d)"),
+                      (int)session->max_stream_count, 
+                      (int)session->max_stream_mem,
+                      session->mplx->workers_limit, 
+                      session->mplx->workers_max, 
+                      session->push_diary->dtype, 
+                      (int)session->push_diary->N);
+    }
     return session;
 }
 
Index: modules/http2/h2_session.h
===================================================================
--- modules/http2/h2_session.h	(revision 1784618)
+++ modules/http2/h2_session.h	(working copy)
@@ -121,6 +121,7 @@
     
     apr_bucket_brigade *bbtmp;      /* brigade for keeping temporary data */
     struct apr_thread_cond_t *iowait; /* our cond when trywaiting for data */
+    struct apr_thread_mutex_t *allocator_mutex; /* c->pool->allocator mutex if we created one */
     
     char status[64];                /* status message for scoreboard */
     int last_status_code;           /* the one already reported */
