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 9a93d32  Cancel closing if Http2SendDataFrameResult is NO_WINDOW
9a93d32 is described below

commit 9a93d32863364e01267b5aabd322a9740c695441
Author: Masaori Koshiba <masa...@apache.org>
AuthorDate: Mon Nov 13 16:50:34 2017 +0900

    Cancel closing if Http2SendDataFrameResult is NO_WINDOW
---
 proxy/http2/Http2ConnectionState.cc | 38 ++++++++++++++++++-------------------
 proxy/http2/Http2ConnectionState.h  | 14 +++++++-------
 proxy/http2/Http2Stream.cc          | 22 +++++++++++++--------
 3 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/proxy/http2/Http2ConnectionState.cc 
b/proxy/http2/Http2ConnectionState.cc
index 0368fed..75c489b 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -1236,11 +1236,11 @@ 
Http2ConnectionState::send_data_frames_depends_on_priority()
   ink_release_assert(stream != nullptr);
   Http2StreamDebug(ua_session, stream->get_id(), "top node, point=%d", 
node->point);
 
-  size_t len                       = 0;
-  Http2SendADataFrameResult result = send_a_data_frame(stream, len);
+  size_t len                      = 0;
+  Http2SendDataFrameResult result = send_a_data_frame(stream, len);
 
   switch (result) {
-  case HTTP2_SEND_A_DATA_FRAME_NO_ERROR: {
+  case Http2SendDataFrameResult::NO_ERROR: {
     // No response body to send
     if (len == 0 && !stream->is_body_done()) {
       dependency_tree->deactivate(node, len);
@@ -1249,7 +1249,7 @@ 
Http2ConnectionState::send_data_frames_depends_on_priority()
     }
     break;
   }
-  case HTTP2_SEND_A_DATA_FRAME_DONE: {
+  case Http2SendDataFrameResult::DONE: {
     dependency_tree->deactivate(node, len);
     delete_stream(stream);
     break;
@@ -1264,7 +1264,7 @@ 
Http2ConnectionState::send_data_frames_depends_on_priority()
   return;
 }
 
-Http2SendADataFrameResult
+Http2SendDataFrameResult
 Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t 
&payload_length)
 {
   const ssize_t window_size         = std::min(this->client_rwnd, 
stream->client_rwnd);
@@ -1286,7 +1286,7 @@ Http2ConnectionState::send_a_data_frame(Http2Stream 
*stream, size_t &payload_len
   if (read_available_size > 0) {
     // We only need to check for window size when there is a payload
     if (window_size <= 0) {
-      return HTTP2_SEND_A_DATA_FRAME_NO_WINDOW;
+      return Http2SendDataFrameResult::NO_WINDOW;
     }
     // Copy into the payload buffer. Seems like we should be able to skip this 
copy step
     payload_length = current_reader->read(payload_buffer, 
write_available_size);
@@ -1298,7 +1298,7 @@ Http2ConnectionState::send_a_data_frame(Http2Stream 
*stream, size_t &payload_len
   // If we return here, we never send the END_STREAM in the case of a early 
terminating OS.
   // OK if there is no body yet. Otherwise continue on to send a DATA frame 
and delete the stream
   if (!stream->is_body_done() && payload_length == 0) {
-    return HTTP2_SEND_A_DATA_FRAME_NO_PAYLOAD;
+    return Http2SendDataFrameResult::NO_PAYLOAD;
   }
 
   if (stream->is_body_done() && read_available_size <= write_available_size) {
@@ -1330,13 +1330,13 @@ Http2ConnectionState::send_a_data_frame(Http2Stream 
*stream, size_t &payload_len
     // Setting to the same state shouldn't be erroneous
     stream->change_state(data.header().type, data.header().flags);
 
-    return HTTP2_SEND_A_DATA_FRAME_DONE;
+    return Http2SendDataFrameResult::DONE;
   }
 
-  return HTTP2_SEND_A_DATA_FRAME_NO_ERROR;
+  return Http2SendDataFrameResult::NO_ERROR;
 }
 
-void
+Http2SendDataFrameResult
 Http2ConnectionState::send_data_frames(Http2Stream *stream)
 {
   // To follow RFC 7540 must not send more frames other than priority on
@@ -1345,27 +1345,25 @@ Http2ConnectionState::send_data_frames(Http2Stream 
*stream)
       stream->get_state() == Http2StreamState::HTTP2_STREAM_STATE_CLOSED) {
     Http2StreamDebug(this->ua_session, stream->get_id(), "Shutdown half closed 
local stream");
     this->delete_stream(stream);
-    return;
+    return Http2SendDataFrameResult::NO_ERROR;
   }
 
-  size_t len = 0;
-  while (true) {
-    Http2SendADataFrameResult result = send_a_data_frame(stream, len);
+  size_t len                      = 0;
+  Http2SendDataFrameResult result = Http2SendDataFrameResult::NO_ERROR;
+  while (result == Http2SendDataFrameResult::NO_ERROR) {
+    result = send_a_data_frame(stream, len);
 
-    if (result == HTTP2_SEND_A_DATA_FRAME_DONE) {
+    if (result == Http2SendDataFrameResult::DONE) {
       // Delete a stream immediately
       // TODO its should not be deleted for a several time to handling
       // RST_STREAM and WINDOW_UPDATE.
       // See 'closed' state written at [RFC 7540] 5.1.
       Http2StreamDebug(this->ua_session, stream->get_id(), "Shutdown stream");
       this->delete_stream(stream);
-      break;
-    } else if (result == HTTP2_SEND_A_DATA_FRAME_NO_ERROR) {
-      continue;
-    } else {
-      break;
     }
   }
+
+  return result;
 }
 
 void
diff --git a/proxy/http2/Http2ConnectionState.h 
b/proxy/http2/Http2ConnectionState.h
index a4ffd76..1a640b0 100644
--- a/proxy/http2/Http2ConnectionState.h
+++ b/proxy/http2/Http2ConnectionState.h
@@ -31,11 +31,11 @@
 
 class Http2ClientSession;
 
-enum Http2SendADataFrameResult {
-  HTTP2_SEND_A_DATA_FRAME_NO_ERROR   = 0,
-  HTTP2_SEND_A_DATA_FRAME_NO_WINDOW  = 1,
-  HTTP2_SEND_A_DATA_FRAME_NO_PAYLOAD = 2,
-  HTTP2_SEND_A_DATA_FRAME_DONE       = 3,
+enum class Http2SendDataFrameResult {
+  NO_ERROR   = 0,
+  NO_WINDOW  = 1,
+  NO_PAYLOAD = 2,
+  DONE       = 3,
 };
 
 enum Http2ShutdownState { NOT_INITIATED, INITIATED, IN_PROGRESS };
@@ -218,8 +218,8 @@ public:
   // HTTP/2 frame sender
   void schedule_stream(Http2Stream *stream);
   void send_data_frames_depends_on_priority();
-  void send_data_frames(Http2Stream *stream);
-  Http2SendADataFrameResult send_a_data_frame(Http2Stream *stream, size_t 
&payload_length);
+  Http2SendDataFrameResult send_data_frames(Http2Stream *stream);
+  Http2SendDataFrameResult send_a_data_frame(Http2Stream *stream, size_t 
&payload_length);
   void send_headers_frame(Http2Stream *stream);
   void send_push_promise_frame(Http2Stream *stream, URL &url, const MIMEField 
*accept_encoding);
   void send_rst_stream_frame(Http2StreamId id, Http2ErrorCode ec);
diff --git a/proxy/http2/Http2Stream.cc b/proxy/http2/Http2Stream.cc
index f1cdaa4..e42a3f1 100644
--- a/proxy/http2/Http2Stream.cc
+++ b/proxy/http2/Http2Stream.cc
@@ -315,26 +315,32 @@ void
 Http2Stream::do_io_close(int /* flags */)
 {
   SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
-  super::release(nullptr);
+
   if (!closed) {
-    Http2StreamDebug("do_io_close");
+    if (parent && this->is_client_state_writeable()) {
+      // Make sure any trailing end of stream frames are sent
+      // Wee will be removed at send_data_frames or closing connection phase
+      Http2SendDataFrameResult result = static_cast<Http2ClientSession 
*>(parent)->connection_state.send_data_frames(this);
+      if (result == Http2SendDataFrameResult::NO_WINDOW) {
+        Http2StreamDebug("cancel closing");
+        return;
+      } else {
+        Http2StreamDebug("continue closing");
+      }
+    }
 
     // When we get here, the SM has initiated the shutdown.  Either it 
received a WRITE_COMPLETE, or it is shutting down.  Any
     // remaining IO operations back to client should be abandoned.  The 
SM-side buffers backing these operations will be deleted
     // by the time this is called from transaction_done.
     closed = true;
 
-    if (parent && this->is_client_state_writeable()) {
-      // Make sure any trailing end of stream frames are sent
-      // Wee will be removed at send_data_frames or closing connection phase
-      static_cast<Http2ClientSession 
*>(parent)->connection_state.send_data_frames(this);
-    }
-
     clear_timers();
     clear_io_events();
 
     // Wait until transaction_done is called from HttpSM to signal that the 
TXN_CLOSE hook has been executed
   }
+
+  super::release(nullptr);
 }
 
 /*

-- 
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].

Reply via email to