This is an automated email from the ASF dual-hosted git repository.

shinrich pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 36a28db  fix instability caused by HTTP2_SESSION_EVENT_FINI
36a28db is described below

commit 36a28db62d36f248f9b003bab84aaadb370809fe
Author: Fei Deng <duke8...@gmail.com>
AuthorDate: Thu Mar 1 13:58:16 2018 -0600

    fix instability caused by HTTP2_SESSION_EVENT_FINI
---
 proxy/http2/Http2ConnectionState.cc | 28 +++++++++++++++++++++-------
 proxy/http2/Http2ConnectionState.h  |  5 +++++
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/proxy/http2/Http2ConnectionState.cc 
b/proxy/http2/Http2ConnectionState.cc
index caa114d..15cd17d 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -836,6 +836,9 @@ static const http2_frame_dispatch 
frame_handlers[HTTP2_FRAME_TYPE_MAX] = {
 int
 Http2ConnectionState::main_event_handler(int event, void *edata)
 {
+  if (edata == fini_event) {
+    fini_event = nullptr;
+  }
   ++recursion;
   switch (event) {
   // Initialize HTTP/2 Connection
@@ -910,7 +913,9 @@ Http2ConnectionState::main_event_handler(int event, void 
*edata)
         }
         this->send_goaway_frame(this->latest_streamid_in, error.code);
         this->ua_session->set_half_close_local_flag(true);
-        this_ethread()->schedule_imm_local((Continuation *)this, 
HTTP2_SESSION_EVENT_FINI);
+        if (fini_event == nullptr) {
+          fini_event = this_ethread()->schedule_imm_local((Continuation 
*)this, HTTP2_SESSION_EVENT_FINI);
+        }
 
         // The streams will be cleaned up by the HTTP2_SESSION_EVENT_FINI event
         // The Http2ClientSession will shutdown because 
connection_state.is_state_closed() will be true
@@ -970,8 +975,11 @@ Http2ConnectionState::main_event_handler(int event, void 
*edata)
 }
 
 int
-Http2ConnectionState::state_closed(int /* event */, void * /* edata */)
+Http2ConnectionState::state_closed(int /* event */, void *edata)
 {
+  if (edata == fini_event) {
+    fini_event = nullptr;
+  }
   return 0;
 }
 
@@ -1197,8 +1205,8 @@ Http2ConnectionState::release_stream(Http2Stream *stream)
         // Can't do this because we just destroyed right here ^,
         // or we can use a local variable to do it.
         // ua_session = nullptr;
-      } else if (shutdown_state == HTTP2_SHUTDOWN_IN_PROGRESS) {
-        this_ethread()->schedule_imm_local((Continuation *)this, 
HTTP2_SESSION_EVENT_FINI);
+      } else if (shutdown_state == HTTP2_SHUTDOWN_IN_PROGRESS && fini_event == 
nullptr) {
+        fini_event = this_ethread()->schedule_imm_local((Continuation *)this, 
HTTP2_SESSION_EVENT_FINI);
       }
     }
   }
@@ -1438,7 +1446,9 @@ Http2ConnectionState::send_headers_frame(Http2Stream 
*stream)
   if (!stream->change_state(HTTP2_FRAME_TYPE_HEADERS, flags)) {
     this->send_goaway_frame(this->latest_streamid_in, 
Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR);
     this->ua_session->set_half_close_local_flag(true);
-    this_ethread()->schedule_imm_local((Continuation *)this, 
HTTP2_SESSION_EVENT_FINI);
+    if (fini_event == nullptr) {
+      fini_event = this_ethread()->schedule_imm_local((Continuation *)this, 
HTTP2_SESSION_EVENT_FINI);
+    }
 
     h2_hdr.destroy();
     ats_free(buf);
@@ -1615,7 +1625,9 @@ Http2ConnectionState::send_rst_stream_frame(Http2StreamId 
id, Http2ErrorCode ec)
     if (!stream->change_state(HTTP2_FRAME_TYPE_RST_STREAM, 0)) {
       this->send_goaway_frame(this->latest_streamid_in, 
Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR);
       this->ua_session->set_half_close_local_flag(true);
-      this_ethread()->schedule_imm_local((Continuation *)this, 
HTTP2_SESSION_EVENT_FINI);
+      if (fini_event == nullptr) {
+        fini_event = this_ethread()->schedule_imm_local((Continuation *)this, 
HTTP2_SESSION_EVENT_FINI);
+      }
 
       return;
     }
@@ -1651,7 +1663,9 @@ Http2ConnectionState::send_settings_frame(const 
Http2ConnectionSettings &new_set
       if (!http2_write_settings(param, iov)) {
         this->send_goaway_frame(this->latest_streamid_in, 
Http2ErrorCode::HTTP2_ERROR_INTERNAL_ERROR);
         this->ua_session->set_half_close_local_flag(true);
-        this_ethread()->schedule_imm_local((Continuation *)this, 
HTTP2_SESSION_EVENT_FINI);
+        if (fini_event == nullptr) {
+          fini_event = this_ethread()->schedule_imm_local((Continuation 
*)this, HTTP2_SESSION_EVENT_FINI);
+        }
 
         return;
       }
diff --git a/proxy/http2/Http2ConnectionState.h 
b/proxy/http2/Http2ConnectionState.h
index 2395782..b3fe0e8 100644
--- a/proxy/http2/Http2ConnectionState.h
+++ b/proxy/http2/Http2ConnectionState.h
@@ -152,6 +152,10 @@ public:
 
     delete dependency_tree;
     this->ua_session = nullptr;
+
+    if (fini_event) {
+      fini_event->cancel();
+    }
   }
 
   // Event handlers
@@ -307,6 +311,7 @@ private:
   int recursion                     = 0;
   Http2ShutdownState shutdown_state = HTTP2_SHUTDOWN_NONE;
   Event *shutdown_cont_event        = nullptr;
+  Event *fini_event                 = nullptr;
 };
 
 #endif // __HTTP2_CONNECTION_STATE_H__

-- 
To stop receiving notification emails like this one, please contact
shinr...@apache.org.

Reply via email to