]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
flushing and shutdown tuning
authorStefan Eissing <icing@apache.org>
Tue, 17 Nov 2015 14:13:19 +0000 (14:13 +0000)
committerStefan Eissing <icing@apache.org>
Tue, 17 Nov 2015 14:13:19 +0000 (14:13 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1714788 13f79535-47bb-0310-9956-ffa450edef68

modules/http2/h2_conn.c
modules/http2/h2_conn_io.c
modules/http2/h2_conn_io.h
modules/http2/h2_mplx.c
modules/http2/h2_session.c
modules/http2/h2_session.h
modules/http2/h2_stream.c

index 4ee4b37d4cd30b23e5790dc680ef9fd5f2245aa1..663139624e2467c497dc71e9c4224046ae6e447a 100644 (file)
@@ -174,10 +174,12 @@ apr_status_t h2_conn_process(conn_rec *c, request_rec *r)
     }
     
     status = h2_session_process(session);
-    h2_session_close(session);
 
     ap_log_cerror( APLOG_MARK, APLOG_DEBUG, status, session->c,
                   "h2_session(%ld): done", session->id);
+    h2_session_close(session);
+    h2_session_flush(session);
+    /* hereafter session might be gone */
     
     /* Make sure this connection gets closed properly. */
     ap_update_child_status_from_conn(c->sbh, SERVER_CLOSING, c);
index 1fc7d37e9f4193a2d03256418a6e03ef936480cf..7a241146f0160b0eec603ba2f4e6895b5680ac81 100644 (file)
@@ -278,7 +278,7 @@ apr_status_t h2_conn_io_write(h2_conn_io *io,
                       "h2_conn_io: buffering %ld bytes", (long)length);
                       
         if (!APR_BRIGADE_EMPTY(io->output)) {
-            status = h2_conn_io_flush(io);
+            status = h2_conn_io_pass(io);
             io->unflushed = 1;
         }
         
@@ -338,15 +338,15 @@ apr_status_t h2_conn_io_consider_flush(h2_conn_io *io)
         }
         len += io->buflen;
         if (len >= WRITE_BUFFER_SIZE) {
-            return h2_conn_io_flush(io);
+            return h2_conn_io_pass(io);
         }
     }
     return status;
 }
 
-apr_status_t h2_conn_io_flush(h2_conn_io *io)
+static apr_status_t h2_conn_io_flush_int(h2_conn_io *io, int force)
 {
-    if (io->unflushed) {
+    if (io->unflushed || force) {
         apr_status_t status; 
         if (io->buflen > 0) {
             /* something in the buffer, put it in the output brigade */
@@ -356,8 +356,11 @@ apr_status_t h2_conn_io_flush(h2_conn_io *io)
             io->buflen = 0;
         }
         
-        APR_BRIGADE_INSERT_TAIL(io->output,
-                                apr_bucket_flush_create(io->output->bucket_alloc));
+        if (force) {
+            APR_BRIGADE_INSERT_TAIL(io->output,
+                                    apr_bucket_flush_create(io->output->bucket_alloc));
+        }
+        
         /* Send it out */
         status = pass_out(io->output, io);
         
@@ -374,3 +377,12 @@ apr_status_t h2_conn_io_flush(h2_conn_io *io)
     return APR_SUCCESS;
 }
 
+apr_status_t h2_conn_io_flush(h2_conn_io *io)
+{
+    return h2_conn_io_flush_int(io, 1);
+}
+
+apr_status_t h2_conn_io_pass(h2_conn_io *io)
+{
+    return h2_conn_io_flush_int(io, 0);
+}
\ No newline at end of file
index a0cb3977844db000e0c65b4f6ad420c44f41ee8e..4406261a33b1f594428582cfbe34c4255f869c92 100644 (file)
@@ -63,6 +63,7 @@ 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);
 
+apr_status_t h2_conn_io_pass(h2_conn_io *io);
 apr_status_t h2_conn_io_flush(h2_conn_io *io);
 
 #endif /* defined(__mod_h2__h2_conn_io__) */
index 253868461b39b3923b6a4dea728c98ad8dc04b30..f318fd16a071564e83492e4c85301de15148c910 100644 (file)
@@ -114,7 +114,7 @@ h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *parent, h2_workers *workers)
         APR_RING_ELEM_INIT(m, link);
         apr_atomic_set32(&m->refs, 1);
         m->c = c;
-        apr_pool_create_ex(&m->pool, parent, NULL, allocator);
+        apr_pool_create_ex(&m->pool, NULL, NULL, allocator);
         if (!m->pool) {
             return NULL;
         }
index f836c261be7d1da41128773e20d11a14b6ecca83..3a0415f3ff86404f1852c06f94f24f7e7245d80d 100644 (file)
@@ -84,9 +84,8 @@ h2_stream *h2_session_open_stream(h2_session *session, int stream_id)
     return stream;
 }
 
-static apr_status_t h2_session_flush(h2_session *session) 
+apr_status_t h2_session_flush(h2_session *session) 
 {
-    session->flush = 0;
     return h2_conn_io_flush(&session->io);
 }
 
@@ -236,72 +235,6 @@ static int on_data_chunk_recv_cb(nghttp2_session *ngh2, uint8_t flags,
     return 0;
 }
 
-static int before_frame_send_cb(nghttp2_session *ngh2,
-                                const nghttp2_frame *frame,
-                                void *userp)
-{
-    h2_session *session = (h2_session *)userp;
-    (void)ngh2;
-
-    if (session->aborted) {
-        return NGHTTP2_ERR_CALLBACK_FAILURE;
-    }
-    /* Set the need to flush output when we have added one of the 
-     * following frame types */
-    switch (frame->hd.type) {
-        case NGHTTP2_RST_STREAM:
-        case NGHTTP2_PUSH_PROMISE:
-        case NGHTTP2_GOAWAY:
-            session->flush = 1;
-            break;
-        default:
-            break;
-
-    }
-    if (APLOGctrace2(session->c)) {
-        char buffer[256];
-        frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
-                      "h2_session(%ld): before_frame_send %s", 
-                      session->id, buffer);
-    }
-    return 0;
-}
-
-static int on_frame_send_cb(nghttp2_session *ngh2,
-                            const nghttp2_frame *frame,
-                            void *userp)
-{
-    h2_session *session = (h2_session *)userp;
-    (void)ngh2;
-    if (APLOGctrace2(session->c)) {
-        char buffer[256];
-        frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
-                      "h2_session(%ld): on_frame_send %s", 
-                      session->id, buffer);
-    }
-    return 0;
-}
-
-static int on_frame_not_send_cb(nghttp2_session *ngh2,
-                                const nghttp2_frame *frame,
-                                int lib_error_code, void *userp)
-{
-    h2_session *session = (h2_session *)userp;
-    (void)ngh2;
-    
-    if (APLOGctrace2(session->c)) {
-        char buffer[256];
-        
-        frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
-                      "h2_session: callback on_frame_not_send error=%d %s",
-                      lib_error_code, buffer);
-    }
-    return 0;
-}
-
 static apr_status_t stream_release(h2_session *session, 
                                    h2_stream *stream,
                                    uint32_t error_code) 
@@ -616,9 +549,6 @@ static apr_status_t init_callbacks(conn_rec *c, nghttp2_session_callbacks **pcb)
     NGH2_SET_CALLBACK(*pcb, on_frame_recv, on_frame_recv_cb);
     NGH2_SET_CALLBACK(*pcb, on_invalid_frame_recv, on_invalid_frame_recv_cb);
     NGH2_SET_CALLBACK(*pcb, on_data_chunk_recv, on_data_chunk_recv_cb);
-    NGH2_SET_CALLBACK(*pcb, before_frame_send, before_frame_send_cb);
-    NGH2_SET_CALLBACK(*pcb, on_frame_send, on_frame_send_cb);
-    NGH2_SET_CALLBACK(*pcb, on_frame_not_send, on_frame_not_send_cb);
     NGH2_SET_CALLBACK(*pcb, on_stream_close, on_stream_close_cb);
     NGH2_SET_CALLBACK(*pcb, on_begin_headers, on_begin_headers_cb);
     NGH2_SET_CALLBACK(*pcb, on_header, on_header_cb);
@@ -735,10 +665,6 @@ h2_session *h2_session_rcreate(request_rec *r, h2_config *config,
 void h2_session_cleanup(h2_session *session)
 {
     AP_DEBUG_ASSERT(session);
-    if (session->mplx) {
-        h2_mplx_release_and_join(session->mplx, session->iowait);
-        session->mplx = NULL;
-    }
     if (session->ngh2) {
         nghttp2_session_del(session->ngh2);
         session->ngh2 = NULL;
@@ -747,6 +673,10 @@ void h2_session_cleanup(h2_session *session)
         apr_pool_destroy(session->spare);
         session->spare = NULL;
     }
+    if (session->mplx) {
+        h2_mplx_release_and_join(session->mplx, session->iowait);
+        session->mplx = NULL;
+    }
 }
 
 void h2_session_destroy(h2_session *session)
@@ -764,7 +694,6 @@ void h2_session_destroy(h2_session *session)
         session->streams = NULL;
     }
     if (session->pool) {
-        apr_pool_cleanup_kill(session->pool, session, session_pool_cleanup);
         apr_pool_destroy(session->pool);
     }
 }
@@ -774,6 +703,7 @@ void h2_session_eoc_callback(h2_session *session)
 {
     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
                   "session(%ld): cleanup and destroy", session->id);
+    apr_pool_cleanup_kill(session->pool, session, session_pool_cleanup);
     h2_session_destroy(session);
 }
 
@@ -810,7 +740,6 @@ static apr_status_t h2_session_abort_int(h2_session *session, int reason)
                                       strlen(err));
                 nghttp2_session_send(session->ngh2);
             }
-            h2_session_flush(session);
         }
         h2_mplx_abort(session->mplx);
     }
@@ -1033,12 +962,11 @@ apr_status_t h2_session_close(h2_session *session)
     }
     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0,session->c,
                   "h2_session: closing, writing eoc");
-                  
-    h2_session_cleanup(session);
-    h2_conn_io_writeb(&session->io,
-                      h2_bucket_eoc_create(session->c->bucket_alloc, 
-                                           session));
-    return h2_session_flush(session);
+    
+    h2_session_cleanup(session);              
+    return h2_conn_io_writeb(&session->io,
+                             h2_bucket_eoc_create(session->c->bucket_alloc, 
+                                                  session));
 }
 
 static ssize_t stream_data_cb(nghttp2_session *ng2s,
@@ -1400,13 +1328,10 @@ apr_status_t h2_session_process(h2_session *session)
             }
         }
         
-        if (have_written) {
-            h2_session_flush(session);
-        }
-        
         if (wait_micros > 0) {
             ap_log_cerror( APLOG_MARK, APLOG_TRACE3, 0, session->c,
                           "h2_session: wait for data, %ld micros", (long)(wait_micros));
+            h2_conn_io_pass(&session->io);
             status = h2_mplx_out_trywait(session->mplx, wait_micros, session->iowait);
             
             if (status == APR_TIMEUP) {
@@ -1446,7 +1371,7 @@ apr_status_t h2_session_process(h2_session *session)
             }
             
             if (may_block) {
-                h2_session_flush(session);
+                h2_conn_io_flush(&session->io);
                 if (session->c->cs) {
                     session->c->cs->state = (got_streams? CONN_STATE_HANDLER
                                              : CONN_STATE_WRITE_COMPLETION);
index 377efc70b6ceed2619e1d67aa367bb0ad8c0f303..052b0d7e388306126d168c99157dfb3ff94d9512 100644 (file)
@@ -59,7 +59,6 @@ struct h2_session {
     request_rec *r;                 /* the request that started this in case
                                      * of 'h2c', NULL otherwise */
     int aborted;                    /* this session is being aborted */
-    int flush;                      /* if != 0, flush output on next occasion */
     int reprioritize;               /* scheduled streams priority needs to 
                                      * be re-evaluated */
     apr_size_t frames_received;     /* number of http/2 frames received */
@@ -156,6 +155,12 @@ apr_status_t h2_session_start(h2_session *session, int *rv);
  */
 apr_status_t h2_session_abort(h2_session *session, apr_status_t reason, int rv);
 
+/**
+ * Pass any buffered output data through the connection filters.
+ * @param session the session to flush
+ */
+apr_status_t h2_session_flush(h2_session *session);
+
 /**
  * Called before a session gets destroyed, might flush output etc. 
  */
index a6be8b10ea3fe890768f64a1421b718d89315f8b..ec55ceb698e8d40d546c899df9a4e8e567947edf 100644 (file)
@@ -259,6 +259,8 @@ apr_status_t h2_stream_schedule(h2_stream *stream, int eos,
 {
     apr_status_t status;
     AP_DEBUG_ASSERT(stream);
+    AP_DEBUG_ASSERT(stream->session);
+    AP_DEBUG_ASSERT(stream->session->mplx);
     
     if (!output_open(stream)) {
         return APR_ECONNRESET;