You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2017/03/09 17:33:39 UTC

[trafficserver] branch master updated: Do not callback one SM EVENT_ERROR twice.

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

zwoop 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  aee3f3b   Do not callback one SM EVENT_ERROR twice.
aee3f3b is described below

commit aee3f3bb1b9abdf5a6a7fe5abf4f9e2bc8b75db3
Author: Oknet Xu <xu...@skyguard.com.cn>
AuthorDate: Thu Mar 9 12:51:27 2017 +0800

    Do not callback one SM EVENT_ERROR twice.
    
    After #947 (c1ac5f) and #1522 (a128d5) , the EVENT_ERROR which caused by
    EPOLLERR will be sent to read.vio._cont first and then write.vio._cont.
    
    The reader SM could close or shutdown(WRITE) the VC, but we do not check
    these operations before we callback write.vio._cont. The SM would
    received EVENT_ERROR twice if write.vio._cont == read.vio._cont.
---
 iocore/net/UnixNetVConnection.cc | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index de27549..81bfde2 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -271,9 +271,22 @@ read_from_net(NetHandler *nh, UnixNetVConnection *vc, EThread *thread)
 
     // if it is a non-temporary error, we should die appropriately
     if (err && err != EAGAIN && err != EINTR) {
-      read_signal_error(nh, vc, err);
+      Continuation *reader_cont = vc->read.vio._cont;
+
+      if (read_signal_error(nh, vc, err) == EVENT_DONE) {
+        return;
+      }
+      // If vc is closed or shutdown(WRITE) in last read_signal_error callback,
+      //   or reader_cont is same as write.vio._cont.
+      // Then we must clear the write.error to avoid callback EVENT_ERROR to SM by write_ready_list.
+      if (vc->closed || (vc->f.shutdown & NET_VC_SHUTDOWN_WRITE) || reader_cont == vc->write.vio._cont) {
+        vc->write.error = 0;
+      }
       return;
     }
+
+    // clear read.error if it is non-fatal error
+    vc->read.error = 0;
   }
 
   // if it is not enabled.
@@ -450,9 +463,14 @@ write_to_net_io(NetHandler *nh, UnixNetVConnection *vc, EThread *thread)
     }
 
     if (err && err != EAGAIN && err != EINTR) {
+      // Here is differ to net_read_io since read_signal_error always callback first.
+      // NetHandler::mainNetEvent() is always handle read_ready_list first and then write_ready_list.
       write_signal_error(nh, vc, err);
       return;
     }
+
+    // clear write.error if it is non-fatal error.
+    vc->write.error = 0;
   }
 
   // This function will always return true unless

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