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

zwoop pushed a commit to branch 8.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit b537c7e300e5ac2345f7139fdad628ad40e07dc4
Author: Susan Hinrichs <[email protected]>
AuthorDate: Mon Feb 10 23:27:55 2020 +0000

    Another option to fix potential HTTP/2 vio stall
    
    (cherry picked from commit 87e79069f07daf17f54958de1d1f9d4198ccc266)
    
    Conflicts:
        proxy/http2/Http2Stream.cc
        proxy/http2/Http2Stream.h
---
 proxy/http2/Http2Stream.cc | 73 +++++++++++++++++++++-------------------------
 proxy/http2/Http2Stream.h  |  4 ++-
 2 files changed, 36 insertions(+), 41 deletions(-)

diff --git a/proxy/http2/Http2Stream.cc b/proxy/http2/Http2Stream.cc
index e3fa693..5107a3d 100644
--- a/proxy/http2/Http2Stream.cc
+++ b/proxy/http2/Http2Stream.cc
@@ -76,7 +76,13 @@ Http2Stream::main_event_handler(int event, void *edata)
 
   Event *e = static_cast<Event *>(edata);
   reentrancy_count++;
-  if (e == cross_thread_event) {
+  if (e == _read_vio_event) {
+    this->signal_read_event(e->callback_event);
+    return 0;
+  } else if (e == _write_vio_event) {
+    this->signal_write_event(e->callback_event);
+    return 0;
+  } else if (e == cross_thread_event) {
     cross_thread_event = nullptr;
   } else if (e == active_event) {
     event        = VC_EVENT_ACTIVE_TIMEOUT;
@@ -98,41 +104,17 @@ Http2Stream::main_event_handler(int event, void *edata)
   case VC_EVENT_ACTIVE_TIMEOUT:
   case VC_EVENT_INACTIVITY_TIMEOUT:
     if (current_reader && read_vio.ntodo() > 0) {
-      MUTEX_TRY_LOCK(lock, read_vio.mutex, this_ethread());
-      if (lock.is_locked()) {
-        read_vio.cont->handleEvent(event, &read_vio);
-      } else {
-        if (this->_read_vio_event) {
-          this->_read_vio_event->cancel();
-        }
-        this->_read_vio_event = this_ethread()->schedule_imm(read_vio.cont, 
event, &read_vio);
-      }
+      this->signal_read_event(event);
     } else if (current_reader && write_vio.ntodo() > 0) {
-      MUTEX_TRY_LOCK(lock, write_vio.mutex, this_ethread());
-      if (lock.is_locked()) {
-        write_vio.cont->handleEvent(event, &write_vio);
-      } else {
-        if (this->_write_vio_event) {
-          this->_write_vio_event->cancel();
-        }
-        this->_write_vio_event = this_ethread()->schedule_imm(write_vio.cont, 
event, &write_vio);
-      }
+      this->signal_write_event(event);
     }
     break;
   case VC_EVENT_WRITE_READY:
   case VC_EVENT_WRITE_COMPLETE:
     inactive_timeout_at = Thread::get_hrtime() + inactive_timeout;
     if (e->cookie == &write_vio) {
-      if (write_vio.mutex) {
-        MUTEX_TRY_LOCK(lock, write_vio.mutex, this_ethread());
-        if (lock.is_locked() && write_vio.cont && this->current_reader) {
-          write_vio.cont->handleEvent(event, &write_vio);
-        } else {
-          if (this->_write_vio_event) {
-            this->_write_vio_event->cancel();
-          }
-          this->_write_vio_event = 
this_ethread()->schedule_imm(write_vio.cont, event, &write_vio);
-        }
+      if (write_vio.mutex && write_vio.cont && this->current_reader) {
+        this->signal_write_event(event);
       }
     } else {
       update_write_request(write_vio.get_reader(), INT64_MAX, true);
@@ -142,16 +124,8 @@ Http2Stream::main_event_handler(int event, void *edata)
   case VC_EVENT_READ_READY:
     inactive_timeout_at = Thread::get_hrtime() + inactive_timeout;
     if (e->cookie == &read_vio) {
-      if (read_vio.mutex) {
-        MUTEX_TRY_LOCK(lock, read_vio.mutex, this_ethread());
-        if (lock.is_locked() && read_vio.cont && this->current_reader) {
-          read_vio.cont->handleEvent(event, &read_vio);
-        } else {
-          if (this->_read_vio_event) {
-            this->_read_vio_event->cancel();
-          }
-          this->_read_vio_event = this_ethread()->schedule_imm(read_vio.cont, 
event, &read_vio);
-        }
+      if (read_vio.mutex && read_vio.cont && this->current_reader) {
+        signal_read_event(event);
       }
     } else {
       this->update_read_request(INT64_MAX, true);
@@ -673,7 +647,26 @@ Http2Stream::signal_read_event(int event)
     if (this->_read_vio_event) {
       this->_read_vio_event->cancel();
     }
-    this->_read_vio_event = this_ethread()->schedule_imm(read_vio.cont, event, 
&read_vio);
+    this->_read_vio_event = this_ethread()->schedule_in(this, retry_delay, 
event, &read_vio);
+  }
+}
+
+void
+Http2Stream::signal_write_event(int event)
+{
+  if (this->write_vio.cont == nullptr || this->write_vio.cont->mutex == 
nullptr || this->write_vio.op == VIO::NONE) {
+    return;
+  }
+
+  MUTEX_TRY_LOCK(lock, write_vio.cont->mutex, this_ethread());
+  if (lock.is_locked()) {
+    inactive_timeout_at = Thread::get_hrtime() + inactive_timeout;
+    this->write_vio.cont->handleEvent(event, &this->write_vio);
+  } else {
+    if (this->_write_vio_event) {
+      this->_write_vio_event->cancel();
+    }
+    this->_write_vio_event = this_ethread()->schedule_in(this, retry_delay, 
event, &write_vio);
   }
 }
 
diff --git a/proxy/http2/Http2Stream.h b/proxy/http2/Http2Stream.h
index 461f228..fc52cf3 100644
--- a/proxy/http2/Http2Stream.h
+++ b/proxy/http2/Http2Stream.h
@@ -49,7 +49,8 @@ enum class Http2StreamMilestone {
 class Http2Stream : public ProxyClientTransaction
 {
 public:
-  using super = ProxyClientTransaction; ///< Parent type.
+  const int retry_delay = HRTIME_MSECONDS(10);
+  using super           = ProxyClientTransaction; ///< Parent type.
 
   Http2Stream(Http2StreamId sid = 0, ssize_t initial_rwnd = 
Http2::initial_window_size);
 
@@ -75,6 +76,7 @@ public:
   void update_write_request(IOBufferReader *buf_reader, int64_t write_len, 
bool send_update);
 
   void signal_read_event(int event);
+  void signal_write_event(int event);
   void signal_write_event(bool call_update);
 
   void restart_sending();

Reply via email to