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

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


The following commit(s) were added to refs/heads/9.1.x by this push:
     new cbbf345  Save and propagate epoll network error (#7809)
cbbf345 is described below

commit cbbf3456f29dbdd7b7663f4ddcc1d3727513fab6
Author: Susan Hinrichs <[email protected]>
AuthorDate: Mon May 17 19:23:48 2021 -0500

    Save and propagate epoll network error (#7809)
    
    (cherry picked from commit 23174f43ba543c9f56916e5d6aadb7a22f349355)
---
 iocore/net/NetEvent.h            | 17 +++++++++++++++++
 iocore/net/UnixNet.cc            | 19 ++++++++-----------
 iocore/net/UnixNetVConnection.cc | 12 ++++++++++++
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/iocore/net/NetEvent.h b/iocore/net/NetEvent.h
index 94e96fe..534f309 100644
--- a/iocore/net/NetEvent.h
+++ b/iocore/net/NetEvent.h
@@ -55,6 +55,9 @@ public:
   // Close when EventIO close;
   virtual int close() = 0;
 
+  bool has_error() const;
+  void set_error_from_socket();
+
   // get fd
   virtual int get_fd()                   = 0;
   virtual Ptr<ProxyMutex> &get_mutex()   = 0;
@@ -65,6 +68,7 @@ public:
   NetState write{};
 
   int closed     = 0;
+  int error      = 0;
   NetHandler *nh = nullptr;
 
   ink_hrtime inactivity_timeout_in      = 0;
@@ -94,3 +98,16 @@ public:
     } f;
   };
 };
+
+inline bool
+NetEvent::has_error() const
+{
+  return error != 0;
+}
+
+inline void
+NetEvent::set_error_from_socket()
+{
+  socklen_t errlen = sizeof(error);
+  getsockopt(this->get_fd(), SOL_SOCKET, SO_ERROR, (void *)&error, &errlen);
+}
diff --git a/iocore/net/UnixNet.cc b/iocore/net/UnixNet.cc
index 19ea5ae..ca803ff 100644
--- a/iocore/net/UnixNet.cc
+++ b/iocore/net/UnixNet.cc
@@ -507,27 +507,24 @@ NetHandler::waitForActivity(ink_hrtime timeout)
       if (cop_list.in(ne)) {
         cop_list.remove(ne);
       }
-      if (get_ev_events(pd, x) & (EVENTIO_READ | EVENTIO_ERROR)) {
+      int flags = get_ev_events(pd, x);
+      if (flags & (EVENTIO_ERROR)) {
+        ne->set_error_from_socket();
+      }
+      if (flags & (EVENTIO_READ)) {
         ne->read.triggered = 1;
         if (!read_ready_list.in(ne)) {
           read_ready_list.enqueue(ne);
-        } else if (get_ev_events(pd, x) & EVENTIO_ERROR) {
-          // check for unhandled epoll events that should be handled
-          Debug("iocore_net_main", "Unhandled epoll event on read: 0x%04x 
read.enabled=%d closed=%d read.netready_queue=%d",
-                get_ev_events(pd, x), ne->read.enabled, ne->closed, 
read_ready_list.in(ne));
         }
       }
-      if (get_ev_events(pd, x) & (EVENTIO_WRITE | EVENTIO_ERROR)) {
+      if (flags & (EVENTIO_WRITE)) {
         ne->write.triggered = 1;
         if (!write_ready_list.in(ne)) {
           write_ready_list.enqueue(ne);
-        } else if (get_ev_events(pd, x) & EVENTIO_ERROR) {
-          // check for unhandled epoll events that should be handled
-          Debug("iocore_net_main", "Unhandled epoll event on write: 0x%04x 
write.enabled=%d closed=%d write.netready_queue=%d",
-                get_ev_events(pd, x), ne->write.enabled, ne->closed, 
write_ready_list.in(ne));
         }
-      } else if (!(get_ev_events(pd, x) & EVENTIO_READ)) {
+      } else if (!(flags & (EVENTIO_READ))) {
         Debug("iocore_net_main", "Unhandled epoll event: 0x%04x", 
get_ev_events(pd, x));
+        ink_release_assert(false);
       }
     } else if (epd->type == EVENTIO_DNS_CONNECTION) {
       if (epd->data.dnscon != nullptr) {
diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index 00ca4cf..7b297a7 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -199,6 +199,12 @@ read_from_net(NetHandler *nh, UnixNetVConnection *vc, 
EThread *thread)
     return;
   }
 
+  if (vc->has_error()) {
+    vc->lerrno = vc->error;
+    vc->readSignalAndUpdate(VC_EVENT_ERROR);
+    return;
+  }
+
   // It is possible that the closed flag got set from HttpSessionManager in the
   // global session pool case.  If so, the closed flag should be stable once 
we get the
   // s->vio.mutex (the global session pool mutex).
@@ -361,6 +367,12 @@ write_to_net_io(NetHandler *nh, UnixNetVConnection *vc, 
EThread *thread)
     return;
   }
 
+  if (vc->has_error()) {
+    vc->lerrno = vc->error;
+    write_signal_and_update(VC_EVENT_ERROR, vc);
+    return;
+  }
+
   // This function will always return true unless
   // vc is an SSLNetVConnection.
   if (!vc->getSSLHandShakeComplete()) {

Reply via email to