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

mochen 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 003e9ce2b9 Use dynamic dispatch for EventIO (#10035)
003e9ce2b9 is described below

commit 003e9ce2b90df26fcc06aba377af9e261c8f6a4a
Author: Mo Chen <moc...@apache.org>
AuthorDate: Mon Jul 31 10:34:38 2023 -0500

    Use dynamic dispatch for EventIO (#10035)
    
    Instead of using branches, use dynamic dispatch to process each EventIO. 
Mainly this helps with code organization, and untangles dependencies in iocore.
    
    Testing shows dynamic dispatch to be no worse than branching (approximately 
0.5% +- 0.2% better rps).
---
 iocore/dns/CMakeLists.txt             |  1 +
 iocore/dns/DNS.cc                     |  2 +-
 iocore/dns/DNSEventIO.cc              | 35 ++++++++++++++++
 iocore/dns/DNSEventIO.h               | 46 +++++++++++++++++++++
 iocore/dns/Makefile.am                |  1 +
 iocore/dns/P_DNSConnection.h          |  5 +--
 iocore/io_uring/IOUringEventIO.cc     | 41 +++++++++++++++++++
 iocore/io_uring/IOUringEventIO.h      | 40 ++++++++++++++++++
 iocore/io_uring/Makefile.am           |  2 +
 iocore/net/AsyncSignalEventIO.cc      | 45 +++++++++++++++++++++
 iocore/net/AsyncSignalEventIO.h       | 39 ++++++++++++++++++
 iocore/net/CMakeLists.txt             |  4 ++
 iocore/net/EventIO.cc                 | 69 -------------------------------
 iocore/net/EventIO.h                  | 62 +++++++++-------------------
 iocore/net/Makefile.am                |  8 ++++
 iocore/net/NetAcceptEventIO.cc        | 37 +++++++++++++++++
 iocore/net/NetAcceptEventIO.h         | 37 +++++++++++++++++
 iocore/net/NetEvent.h                 |  5 ++-
 iocore/net/NetHandler.cc              | 73 +++------------------------------
 iocore/net/NetHandler.h               |  4 --
 iocore/net/P_NetAccept.h              |  4 +-
 iocore/net/P_SSLNetVConnection.h      |  2 +-
 iocore/net/P_UnixNet.h                |  7 ++++
 iocore/net/P_UnixUDPConnection.h      |  3 +-
 iocore/net/QUICNetProcessor_quiche.cc |  2 +-
 iocore/net/ReadWriteEventIO.cc        | 76 +++++++++++++++++++++++++++++++++++
 iocore/net/ReadWriteEventIO.h         | 43 ++++++++++++++++++++
 iocore/net/SSLNetVConnection.cc       |  3 +-
 iocore/net/UDPEventIO.cc              | 52 ++++++++++++++++++++++++
 iocore/net/UDPEventIO.h               | 41 +++++++++++++++++++
 iocore/net/UnixNet.cc                 | 24 ++++++-----
 iocore/net/UnixUDPNet.cc              | 68 +++++++++----------------------
 32 files changed, 624 insertions(+), 257 deletions(-)

diff --git a/iocore/dns/CMakeLists.txt b/iocore/dns/CMakeLists.txt
index 9cd1bd1bd7..b509fbb088 100644
--- a/iocore/dns/CMakeLists.txt
+++ b/iocore/dns/CMakeLists.txt
@@ -19,6 +19,7 @@
 add_library(inkdns STATIC
     DNS.cc
     DNSConnection.cc
+    DNSEventIO.cc
     Inline.cc
     SplitDNS.cc
 )
diff --git a/iocore/dns/DNS.cc b/iocore/dns/DNS.cc
index 6a4a016561..40c2ef9c46 100644
--- a/iocore/dns/DNS.cc
+++ b/iocore/dns/DNS.cc
@@ -528,7 +528,7 @@ DNSHandler::open_con(sockaddr const *target, bool failed, 
int icon, bool over_tc
     }
     return false;
   } else {
-    if (cur_con.eio.start(pd, &cur_con, EVENTIO_READ) < 0) {
+    if (cur_con.eio.start(pd, cur_con.fd, EVENTIO_READ) < 0) {
       Error("[iocore_dns] open_con: Failed to add %d server to epoll list\n", 
icon);
     } else {
       cur_con.num   = icon;
diff --git a/iocore/dns/DNSEventIO.cc b/iocore/dns/DNSEventIO.cc
new file mode 100644
index 0000000000..479aa83992
--- /dev/null
+++ b/iocore/dns/DNSEventIO.cc
@@ -0,0 +1,35 @@
+/**
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "DNSEventIO.h"
+#include "P_DNSConnection.h"
+
+int
+DNSEventIO::start(EventLoop l, int fd, int events)
+{
+  return start_common(l, fd, events);
+}
+
+void
+DNSEventIO::process_event(int flags)
+{
+  _c.trigger(); // Make sure the DNSHandler for this con knows we triggered
+  refresh(EVENTIO_READ);
+}
diff --git a/iocore/dns/DNSEventIO.h b/iocore/dns/DNSEventIO.h
new file mode 100644
index 0000000000..9e8c8304e2
--- /dev/null
+++ b/iocore/dns/DNSEventIO.h
@@ -0,0 +1,46 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+/**************************************************************************
+
+  P_DNSConnection.h
+  Description:
+  struct DNSConnection
+  **************************************************************************/
+
+#pragma once
+
+#include "EventIO.h"
+
+struct DNSConnection;
+
+class DNSEventIO : public EventIO
+{
+public:
+  DNSEventIO(DNSConnection &c) : EventIO(), _c(c) {}
+  int start(EventLoop l, int fd, int events);
+  void process_event(int flags) override;
+
+private:
+  DNSConnection &_c;
+};
diff --git a/iocore/dns/Makefile.am b/iocore/dns/Makefile.am
index 33ae418014..7f342f6bf2 100644
--- a/iocore/dns/Makefile.am
+++ b/iocore/dns/Makefile.am
@@ -31,6 +31,7 @@ noinst_LIBRARIES = libinkdns.a
 libinkdns_a_SOURCES = \
        DNS.cc \
        DNSConnection.cc \
+       DNSEventIO.cc \
        I_DNS.h \
        I_DNSProcessor.h \
        I_SplitDNS.h \
diff --git a/iocore/dns/P_DNSConnection.h b/iocore/dns/P_DNSConnection.h
index ed372eb9c2..91fae3699f 100644
--- a/iocore/dns/P_DNSConnection.h
+++ b/iocore/dns/P_DNSConnection.h
@@ -30,9 +30,8 @@
 
 #pragma once
 
-#include "I_EventSystem.h"
+#include "DNSEventIO.h"
 #include "I_DNSProcessor.h"
-#include "EventIO.h"
 
 //
 // Connection
@@ -79,7 +78,7 @@ struct DNSConnection {
   int num = 0;
   Options opt;
   LINK(DNSConnection, link);
-  EventIO eio;
+  DNSEventIO eio{*this};
   InkRand generator;
   DNSHandler *handler = nullptr;
 
diff --git a/iocore/io_uring/IOUringEventIO.cc 
b/iocore/io_uring/IOUringEventIO.cc
new file mode 100644
index 0000000000..fc3eb82269
--- /dev/null
+++ b/iocore/io_uring/IOUringEventIO.cc
@@ -0,0 +1,41 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "IOUringEventIO.h"
+#if TS_USE_LINUX_IO_URING
+#include "I_IO_URING.h"
+
+int
+IOUringEventIO::start(EventLoop l, IOUringContext *h)
+{
+  _h     = h;
+  int fd = _h->register_eventfd();
+  return start_common(l, fd, EVENTIO_READ);
+}
+
+void
+IOUringEventIO::process_event(int flags)
+{
+  _h->service();
+}
+#endif
diff --git a/iocore/io_uring/IOUringEventIO.h b/iocore/io_uring/IOUringEventIO.h
new file mode 100644
index 0000000000..cf0962091c
--- /dev/null
+++ b/iocore/io_uring/IOUringEventIO.h
@@ -0,0 +1,40 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+#include "tscore/ink_config.h"
+#if TS_USE_LINUX_IO_URING
+#include "../net/EventIO.h"
+
+class IOUringContext;
+class IOUringEventIO : public EventIO
+{
+public:
+  IOUringEventIO() : EventIO() {}
+  int start(EventLoop l, IOUringContext *h);
+  void process_event(int flags) override;
+
+private:
+  IOUringContext *_h;
+};
+#endif
diff --git a/iocore/io_uring/Makefile.am b/iocore/io_uring/Makefile.am
index 6430cdac83..64afb55992 100644
--- a/iocore/io_uring/Makefile.am
+++ b/iocore/io_uring/Makefile.am
@@ -25,6 +25,8 @@ AM_CPPFLAGS += \
 noinst_LIBRARIES = libinkuring.a
 
 libinkuring_a_SOURCES = \
+       IOUringEventIO.cc \
+       IOUringEventIO.h \
        io_uring.cc \
        I_IO_URING.h \
        P_IO_URING.h
diff --git a/iocore/net/AsyncSignalEventIO.cc b/iocore/net/AsyncSignalEventIO.cc
new file mode 100644
index 0000000000..f6f615456c
--- /dev/null
+++ b/iocore/net/AsyncSignalEventIO.cc
@@ -0,0 +1,45 @@
+/**@file
+
+   A brief file description
+
+ @section license License
+
+   Licensed to the Apache Software
+   Foundation(ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "AsyncSignalEventIO.h"
+#include "I_EThread.h"
+
+int
+AsyncSignalEventIO::start(EventLoop l, int fd, int events)
+{
+  _fd = fd;
+  return start_common(l, fd, events);
+}
+
+void
+AsyncSignalEventIO::process_event(int flags)
+{
+#if HAVE_EVENTFD
+  uint64_t counter;
+  static_cast<void>(read(_fd, &counter, sizeof(uint64_t)));
+#else
+  char dummy[1024];
+  static_cast<void>(read(_fd, &dummy[0], 1024));
+#endif
+}
diff --git a/iocore/net/AsyncSignalEventIO.h b/iocore/net/AsyncSignalEventIO.h
new file mode 100644
index 0000000000..4786df30dc
--- /dev/null
+++ b/iocore/net/AsyncSignalEventIO.h
@@ -0,0 +1,39 @@
+/**@file
+
+   A brief file description
+
+ @section license License
+
+   Licensed to the Apache Software
+   Foundation(ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+#pragma once
+
+#include "EventIO.h"
+
+class EThread;
+
+class AsyncSignalEventIO : public EventIO
+{
+public:
+  int start(EventLoop l, int fd, int events);
+
+  void process_event(int flags) override;
+
+private:
+  int _fd;
+};
diff --git a/iocore/net/CMakeLists.txt b/iocore/net/CMakeLists.txt
index 5b2e2a082d..4a4426ee0e 100644
--- a/iocore/net/CMakeLists.txt
+++ b/iocore/net/CMakeLists.txt
@@ -19,6 +19,7 @@
 add_library(inknet STATIC
         AcceptOptions.cc
         ALPNSupport.cc
+        AsyncSignalEventIO.cc
         BIO_fastopen.cc
         BoringSSLUtils.cc
         Connection.cc
@@ -28,10 +29,12 @@ add_library(inknet STATIC
         Net.cc
         NetHandler.cc
         NetVCOptions.cc
+        NetAcceptEventIO.cc
         NetVConnection.cc
         PollCont.cc
         PreWarmManager.cc
         ProxyProtocol.cc
+        ReadWriteEventIO.cc
         Socks.cc
         SSLCertLookup.cc
         SSLClientCoordinator.cc
@@ -58,6 +61,7 @@ add_library(inknet STATIC
         TLSSessionResumptionSupport.cc
         TLSSNISupport.cc
         TLSTunnelSupport.cc
+        UDPEventIO.cc
         UDPIOEvent.cc
         UnixConnection.cc
         UnixNet.cc
diff --git a/iocore/net/EventIO.cc b/iocore/net/EventIO.cc
index 7c4b7dafe3..34f4d965fe 100644
--- a/iocore/net/EventIO.cc
+++ b/iocore/net/EventIO.cc
@@ -23,50 +23,6 @@
 
 #include "EventIO.h"
 #include "tscore/ink_assert.h"
-#include "P_Net.h"
-#include "P_UnixNetProcessor.h"
-#include "P_UnixNetVConnection.h"
-#include "P_NetAccept.h"
-#include "P_DNSConnection.h"
-#include "P_UnixUDPConnection.h"
-#include "P_UnixPollDescriptor.h"
-
-int
-EventIO::start(EventLoop l, DNSConnection *vc, int events)
-{
-  type        = EVENTIO_DNS_CONNECTION;
-  data.dnscon = vc;
-  return start_common(l, vc->fd, events);
-}
-int
-EventIO::start(EventLoop l, NetAccept *vc, int events)
-{
-  type    = EVENTIO_NETACCEPT;
-  data.na = vc;
-  return start_common(l, vc->server.fd, events);
-}
-int
-EventIO::start(EventLoop l, NetEvent *ne, int events)
-{
-  type    = EVENTIO_READWRITE_VC;
-  data.ne = ne;
-  return start_common(l, ne->get_fd(), events);
-}
-
-int
-EventIO::start(EventLoop l, UnixUDPConnection *vc, int events)
-{
-  type    = EVENTIO_UDP_CONNECTION;
-  data.uc = vc;
-  return start_common(l, vc->fd, events);
-}
-
-int
-EventIO::start(EventLoop l, int afd, NetEvent *ne, int e)
-{
-  data.ne = ne;
-  return start_common(l, afd, e);
-}
 
 int
 EventIO::start_common(EventLoop l, int afd, int e)
@@ -201,28 +157,3 @@ EventIO::stop()
   }
   return 0;
 }
-
-int
-EventIO::close()
-{
-  if (!this->syscall) {
-    return 0;
-  }
-
-  stop();
-  switch (type) {
-  default:
-    ink_assert(!"case");
-  // fallthrough
-  case EVENTIO_DNS_CONNECTION:
-    return data.dnscon->close();
-    break;
-  case EVENTIO_NETACCEPT:
-    return data.na->server.close();
-    break;
-  case EVENTIO_READWRITE_VC:
-    return data.ne->close();
-    break;
-  }
-  return -1;
-}
diff --git a/iocore/net/EventIO.h b/iocore/net/EventIO.h
index c513691970..684dc5ca33 100644
--- a/iocore/net/EventIO.h
+++ b/iocore/net/EventIO.h
@@ -24,17 +24,12 @@
 #pragma once
 #include "P_UnixPollDescriptor.h"
 
+using EventLoop = PollDescriptor *;
+
 #define USE_EDGE_TRIGGER_EPOLL  1
 #define USE_EDGE_TRIGGER_KQUEUE 1
 #define USE_EDGE_TRIGGER_PORT   1
 
-#define EVENTIO_NETACCEPT      1
-#define EVENTIO_READWRITE_VC   2
-#define EVENTIO_DNS_CONNECTION 3
-#define EVENTIO_UDP_CONNECTION 4
-#define EVENTIO_ASYNC_SIGNAL   5
-#define EVENTIO_IO_URING       6
-
 #if TS_USE_EPOLL
 #ifndef EPOLLEXCLUSIVE
 #define EPOLLEXCLUSIVE 0
@@ -61,15 +56,6 @@
 #define EVENTIO_ERROR (0x010 | 0x002 | 0x020) // ERR PRI HUP
 #endif
 
-struct PollDescriptor;
-using EventLoop = PollDescriptor *;
-
-class NetEvent;
-class UnixUDPConnection;
-class DiskHandler;
-struct DNSConnection;
-struct NetAccept;
-
 /// Unified API for setting and clearing kernel and epoll events.
 struct EventIO {
   int fd = -1; ///< file descriptor, often a system port
@@ -78,31 +64,6 @@ struct EventIO {
 #endif
   EventLoop event_loop = nullptr; ///< the assigned event loop
   bool syscall         = true;    ///< if false, disable all functionality 
(for QUIC)
-  int type             = 0;       ///< class identifier of union data.
-  union {
-    void *untyped;
-    NetEvent *ne;
-    DNSConnection *dnscon;
-    NetAccept *na;
-    UnixUDPConnection *uc;
-    DiskHandler *dh;
-  } data; ///< a kind of continuation
-
-  /** The start methods all logically Setup a class to be called
-     when a file descriptor is available for read or write.
-     The type of the classes vary.  Generally the file descriptor
-     is pulled from the class, but there is one option that lets
-     the file descriptor be expressed directly.
-     @param l the event loop
-     @param events a mask of flags (for details `man epoll_ctl`)
-     @return int the number of events created, -1 is error
-   */
-  int start(EventLoop l, DNSConnection *vc, int events);
-  int start(EventLoop l, NetAccept *vc, int events);
-  int start(EventLoop l, NetEvent *ne, int events);
-  int start(EventLoop l, UnixUDPConnection *vc, int events);
-  int start(EventLoop l, int fd, NetEvent *ne, int events);
-  int start_common(EventLoop l, int fd, int events);
 
   /** Alter the events that will trigger the continuation, for level triggered 
I/O.
      @param events add with positive mask(+EVENTIO_READ), or remove with 
negative mask (-EVENTIO_READ)
@@ -119,8 +80,21 @@ struct EventIO {
   /// Remove the kernel or epoll event. Returns 0 on success.
   int stop();
 
-  /// Remove the epoll event and close the connection. Returns 0 on success.
-  int close();
+  // Process one event that has triggered.
+  virtual void process_event(int flags) = 0;
+
+  EventIO() {}
+  virtual ~EventIO() {}
 
-  EventIO() { data.untyped = nullptr; }
+protected:
+  /** The start methods all logically Setup a class to be called
+     when a file descriptor is available for read or write.
+     The type of the classes vary.  Generally the file descriptor
+     is pulled from the class, but there is one option that lets
+     the file descriptor be expressed directly.
+     @param l the event loop
+     @param events a mask of flags (for details `man epoll_ctl`)
+     @return int the number of events created, -1 is error
+   */
+  int start_common(EventLoop l, int fd, int events);
 };
diff --git a/iocore/net/Makefile.am b/iocore/net/Makefile.am
index b4c0c3895e..def9c7b258 100644
--- a/iocore/net/Makefile.am
+++ b/iocore/net/Makefile.am
@@ -142,6 +142,8 @@ libinknet_a_SOURCES = \
        AcceptOptions.cc \
        AcceptOptions.h \
        ALPNSupport.cc \
+       AsyncSignalEventIO.cc \
+       AsyncSignalEventIO.h \
        BIO_fastopen.cc \
        BIO_fastopen.h \
        BoringSSLUtils.cc \
@@ -161,6 +163,8 @@ libinknet_a_SOURCES = \
        YamlSNIConfig.h \
        YamlSNIConfig.cc \
        Net.cc \
+       NetAcceptEventIO.h \
+       NetAcceptEventIO.cc \
        NetHandler.h \
        NetHandler.cc \
        NetVCOptions.h \
@@ -202,6 +206,8 @@ libinknet_a_SOURCES = \
        PreWarmManager.cc \
        ProxyProtocol.h \
        ProxyProtocol.cc \
+       ReadWriteEventIO.h \
+       ReadWriteEventIO.cc \
        Socks.cc \
        SSLCertLookup.cc \
        SSLClientCoordinator.cc \
@@ -229,6 +235,8 @@ libinknet_a_SOURCES = \
        TLSSNISupport.cc \
        TLSTunnelSupport.cc \
        TLSCertSwitchSupport.cc \
+       UDPEventIO.h \
+       UDPEventIO.cc \
        UDPIOEvent.cc \
        UnixConnection.cc \
        UnixNet.cc \
diff --git a/iocore/net/NetAcceptEventIO.cc b/iocore/net/NetAcceptEventIO.cc
new file mode 100644
index 0000000000..21db723745
--- /dev/null
+++ b/iocore/net/NetAcceptEventIO.cc
@@ -0,0 +1,37 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "NetAcceptEventIO.h"
+#include "P_NetAccept.h"
+
+int
+NetAcceptEventIO::start(EventLoop l, NetAccept *na, int events)
+{
+  _na = na;
+  return start_common(l, _na->server.fd, events);
+}
+void
+NetAcceptEventIO::process_event(int flags)
+{
+  this_ethread()->schedule_imm(_na);
+}
diff --git a/iocore/net/NetAcceptEventIO.h b/iocore/net/NetAcceptEventIO.h
new file mode 100644
index 0000000000..0e525bba07
--- /dev/null
+++ b/iocore/net/NetAcceptEventIO.h
@@ -0,0 +1,37 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include "EventIO.h"
+
+struct NetAccept;
+
+struct NetAcceptEventIO : public EventIO {
+  NetAcceptEventIO() : EventIO() {}
+  int start(EventLoop l, NetAccept *vc, int events);
+  void process_event(int flags) override;
+
+private:
+  NetAccept *_na = nullptr;
+};
diff --git a/iocore/net/NetEvent.h b/iocore/net/NetEvent.h
index 7043ec167a..927c943eb2 100644
--- a/iocore/net/NetEvent.h
+++ b/iocore/net/NetEvent.h
@@ -25,9 +25,10 @@
 
 #include <atomic>
 
-#include "EventIO.h"
 #include "I_EventSystem.h"
 #include "P_UnixNetState.h"
+#include "EventIO.h"
+#include "ReadWriteEventIO.h"
 
 class NetHandler;
 
@@ -67,7 +68,7 @@ public:
   virtual Ptr<ProxyMutex> &get_mutex()   = 0;
   virtual ContFlags &get_control_flags() = 0;
 
-  EventIO ep{};
+  ReadWriteEventIO ep{};
   NetState read{};
   NetState write{};
 
diff --git a/iocore/net/NetHandler.cc b/iocore/net/NetHandler.cc
index b11820aee8..d23554c4ca 100644
--- a/iocore/net/NetHandler.cc
+++ b/iocore/net/NetHandler.cc
@@ -27,7 +27,6 @@
 #include "I_IO_URING.h"
 #endif
 
-#include "P_DNSConnection.h"
 #include "P_Net.h"
 #include "P_UnixNet.h"
 #include "P_UnixNetProcessor.h"
@@ -50,7 +49,7 @@ NetHandler::startIO(NetEvent *ne)
   int res = 0;
 
   PollDescriptor *pd = get_PollDescriptor(this->thread);
-  if (ne->ep.start(pd, ne, EVENTIO_READ | EVENTIO_WRITE) < 0) {
+  if (ne->ep.start(pd, ne, this, EVENTIO_READ | EVENTIO_WRITE) < 0) {
     res = errno;
     // EEXIST should be ok, though it should have been cleared before we got 
back here
     if (errno != EEXIST) {
@@ -306,25 +305,12 @@ NetHandler::mainNetEvent(int event, Event *e)
   }
 }
 
-static void
-net_signal_hook_callback(EThread *thread)
-{
-#if HAVE_EVENTFD
-  uint64_t counter;
-  ATS_UNUSED_RETURN(read(thread->evfd, &counter, sizeof(uint64_t)));
-#else
-  char dummy[1024];
-  ATS_UNUSED_RETURN(read(thread->evpipe[0], &dummy[0], 1024));
-#endif
-}
-
 int
 NetHandler::waitForActivity(ink_hrtime timeout)
 {
   EventIO *epd = nullptr;
 #if TS_USE_LINUX_IO_URING
   IOUringContext *ur = IOUringContext::local_context();
-  bool servicedh     = false;
 #endif
 
   NET_INCREMENT_DYN_STAT(net_handler_run_stat);
@@ -342,67 +328,18 @@ NetHandler::waitForActivity(ink_hrtime timeout)
 
   // Get & Process polling result
   PollDescriptor *pd = get_PollDescriptor(this->thread);
-  NetEvent *ne       = nullptr;
   for (int x = 0; x < pd->result; x++) {
-    epd = static_cast<EventIO *> get_ev_data(pd, x);
-    if (epd->type == EVENTIO_READWRITE_VC) {
-      ne = epd->data.ne;
-      // Remove triggered NetEvent from cop_list because it won't be timeout 
before next InactivityCop runs.
-      if (cop_list.in(ne)) {
-        cop_list.remove(ne);
-      }
-      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);
-        }
-      }
-      if (flags & (EVENTIO_WRITE)) {
-        ne->write.triggered = 1;
-        if (!write_ready_list.in(ne)) {
-          write_ready_list.enqueue(ne);
-        }
-      } else if (!(flags & (EVENTIO_READ))) {
-        Debug("iocore_net_main", "Unhandled epoll event: 0x%04x", flags);
-        // In practice we sometimes see EPOLLERR and EPOLLHUP through there
-        // Anything else would be surprising
-        ink_assert((flags & ~(EVENTIO_ERROR)) == 0);
-        ne->write.triggered = 1;
-        if (!write_ready_list.in(ne)) {
-          write_ready_list.enqueue(ne);
-        }
-      }
-    } else if (epd->type == EVENTIO_DNS_CONNECTION) {
-      if (epd->data.dnscon != nullptr) {
-        epd->data.dnscon->trigger(); // Make sure the DNSHandler for this con 
knows we triggered
-#if defined(USE_EDGE_TRIGGER)
-        epd->refresh(EVENTIO_READ);
-#endif
-      }
-    } else if (epd->type == EVENTIO_ASYNC_SIGNAL) {
-      net_signal_hook_callback(this->thread);
-    } else if (epd->type == EVENTIO_NETACCEPT) {
-      this->thread->schedule_imm(epd->data.na);
-#if TS_USE_LINUX_IO_URING
-    } else if (epd->type == EVENTIO_IO_URING) {
-      servicedh = true;
-#endif
-    }
+    epd       = static_cast<EventIO *> get_ev_data(pd, x);
+    int flags = get_ev_events(pd, x);
+    epd->process_event(flags);
     ev_next_event(pd, x);
   }
 
   pd->result = 0;
 
   process_ready_list();
-
 #if TS_USE_LINUX_IO_URING
-  if (servicedh) {
-    ur->service();
-  }
+  ur->service();
 #endif
 
   return EVENT_CONT;
diff --git a/iocore/net/NetHandler.h b/iocore/net/NetHandler.h
index b733fced2b..9103aeabd3 100644
--- a/iocore/net/NetHandler.h
+++ b/iocore/net/NetHandler.h
@@ -107,10 +107,6 @@ public:
   Que(NetEvent, active_queue_link) active_queue;
   uint32_t active_queue_size = 0;
 
-#ifdef TS_USE_LINUX_IO_URING
-  EventIO uring_evio;
-#endif
-
   /// configuration settings for managing the active and keep-alive queues
   struct Config {
     uint32_t max_connections_in                 = 0;
diff --git a/iocore/net/P_NetAccept.h b/iocore/net/P_NetAccept.h
index e116affe51..ddeeb8b5af 100644
--- a/iocore/net/P_NetAccept.h
+++ b/iocore/net/P_NetAccept.h
@@ -38,8 +38,8 @@
  ****************************************************************************/
 #pragma once
 
-#include "EventIO.h"
 #include "I_NetProcessor.h"
+#include "NetAcceptEventIO.h"
 #include <vector>
 #include "tscore/ink_platform.h"
 #include "P_Connection.h"
@@ -91,7 +91,7 @@ struct NetAccept : public Continuation {
   int id                      = -1;
   Ptr<NetAcceptAction> action_;
   SSLNextProtocolAccept *snpa = nullptr;
-  EventIO ep;
+  NetAcceptEventIO ep;
 
   HttpProxyPort *proxyPort = nullptr;
   AcceptOptions opt;
diff --git a/iocore/net/P_SSLNetVConnection.h b/iocore/net/P_SSLNetVConnection.h
index 74e68f32ef..f3f78da311 100644
--- a/iocore/net/P_SSLNetVConnection.h
+++ b/iocore/net/P_SSLNetVConnection.h
@@ -463,7 +463,7 @@ private:
   std::unique_ptr<char[]> _ca_cert_file;
   std::unique_ptr<char[]> _ca_cert_dir;
 
-  EventIO async_ep{};
+  ReadWriteEventIO async_ep{};
 
   // early data related stuff
 #if TS_HAS_TLS_EARLY_DATA
diff --git a/iocore/net/P_UnixNet.h b/iocore/net/P_UnixNet.h
index dc1a8d3086..3f1b8454b1 100644
--- a/iocore/net/P_UnixNet.h
+++ b/iocore/net/P_UnixNet.h
@@ -30,6 +30,13 @@
 #include "PollCont.h"
 #include "EventIO.h"
 #include "NetHandler.h"
+#include "tscore/ink_platform.h"
+
+#if TS_USE_LINUX_IO_URING
+#include "IOUringEventIO.h"
+#endif
+
+#include "P_DNSConnection.h"
 #include "P_Net.h"
 #include "P_NetAccept.h"
 #include "P_UnixNetProcessor.h"
diff --git a/iocore/net/P_UnixUDPConnection.h b/iocore/net/P_UnixUDPConnection.h
index abed93ed32..27cdb2da29 100644
--- a/iocore/net/P_UnixUDPConnection.h
+++ b/iocore/net/P_UnixUDPConnection.h
@@ -31,6 +31,7 @@
 #pragma once
 
 #include "P_UDPConnection.h"
+#include "UDPEventIO.h"
 
 class UnixUDPConnection : public UDPConnectionInternal
 {
@@ -48,7 +49,7 @@ public:
   int onCallbackQueue    = 0;
   Action *callbackAction = nullptr;
   EThread *ethread       = nullptr;
-  EventIO ep;
+  UDPEventIO ep;
 
   UnixUDPConnection(int the_fd);
   ~UnixUDPConnection() override;
diff --git a/iocore/net/QUICNetProcessor_quiche.cc 
b/iocore/net/QUICNetProcessor_quiche.cc
index 2326aac250..b6c1932759 100644
--- a/iocore/net/QUICNetProcessor_quiche.cc
+++ b/iocore/net/QUICNetProcessor_quiche.cc
@@ -170,7 +170,7 @@ QUICNetProcessor::connect_re(Continuation *cont, sockaddr 
const *remote_addr, Ne
   PollDescriptor *pd = pc->pollDescriptor;
 
   errno   = 0;
-  int res = con->ep.start(pd, con, EVENTIO_READ);
+  int res = con->ep.start(pd, con, 
get_UDPNetHandler(cont->getThreadAffinity()), EVENTIO_READ);
   if (res < 0) {
     Debug("udpnet", "Error: %s (%d)", strerror(errno), errno);
   }
diff --git a/iocore/net/ReadWriteEventIO.cc b/iocore/net/ReadWriteEventIO.cc
new file mode 100644
index 0000000000..0e86d69b10
--- /dev/null
+++ b/iocore/net/ReadWriteEventIO.cc
@@ -0,0 +1,76 @@
+/**@file
+
+   A brief file description
+
+ @section license License
+
+   Licensed to the Apache Software
+   Foundation(ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "ReadWriteEventIO.h"
+#include "NetHandler.h"
+
+int
+ReadWriteEventIO::start(EventLoop l, NetEvent *ne, NetHandler *nh, int events)
+{
+  _ne = ne;
+  _nh = nh;
+  return start_common(l, ne->get_fd(), events);
+}
+
+int
+ReadWriteEventIO::start(EventLoop l, int afd, NetEvent *ne, NetHandler *nh, 
int events)
+{
+  _ne = ne;
+  _nh = nh;
+  return start_common(l, afd, events);
+}
+
+void
+ReadWriteEventIO::process_event(int flags)
+{
+  // Remove triggered NetEvent from cop_list because it won't be timeout before
+  // next InactivityCop runs.
+  if (_nh->cop_list.in(_ne)) {
+    _nh->cop_list.remove(_ne);
+  }
+  if (flags & (EVENTIO_ERROR)) {
+    _ne->set_error_from_socket();
+  }
+  if (flags & (EVENTIO_READ)) {
+    _ne->read.triggered = 1;
+    if (!_nh->read_ready_list.in(_ne)) {
+      _nh->read_ready_list.enqueue(_ne);
+    }
+  }
+  if (flags & (EVENTIO_WRITE)) {
+    _ne->write.triggered = 1;
+    if (!_nh->write_ready_list.in(_ne)) {
+      _nh->write_ready_list.enqueue(_ne);
+    }
+  } else if (!(flags & (EVENTIO_READ))) {
+    Debug("iocore_net_main", "Unhandled epoll event: 0x%04x", flags);
+    // In practice we sometimes see EPOLLERR and EPOLLHUP through there
+    // Anything else would be surprising
+    ink_assert((flags & ~(EVENTIO_ERROR)) == 0);
+    _ne->write.triggered = 1;
+    if (!_nh->write_ready_list.in(_ne)) {
+      _nh->write_ready_list.enqueue(_ne);
+    }
+  }
+}
diff --git a/iocore/net/ReadWriteEventIO.h b/iocore/net/ReadWriteEventIO.h
new file mode 100644
index 0000000000..2152e3715f
--- /dev/null
+++ b/iocore/net/ReadWriteEventIO.h
@@ -0,0 +1,43 @@
+/**@file
+
+   A brief file description
+
+ @section license License
+
+   Licensed to the Apache Software
+   Foundation(ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include "EventIO.h"
+
+class NetHandler;
+class NetEvent;
+
+class ReadWriteEventIO : public EventIO
+{
+public:
+  ReadWriteEventIO() : EventIO() {}
+  int start(EventLoop l, NetEvent *ne, NetHandler *nh, int events);
+  int start(EventLoop l, int afd, NetEvent *ne, NetHandler *nh, int events);
+  void process_event(int flags) override;
+
+private:
+  NetEvent *_ne   = nullptr;
+  NetHandler *_nh = nullptr;
+};
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index f19f83dbed..8bbb8cbfec 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -1293,8 +1293,7 @@ SSLNetVConnection::sslServerHandShakeEvent(int &err)
           // Have to have the read NetState enabled because we are using it 
for the signal vc
           read.enabled       = true;
           PollDescriptor *pd = get_PollDescriptor(this_ethread());
-          this->async_ep.start(pd, waitfds[0], static_cast<NetEvent *>(this), 
EVENTIO_READ);
-          this->async_ep.type = EVENTIO_READWRITE_VC;
+          this->async_ep.start(pd, waitfds[0], static_cast<NetEvent *>(this), 
get_NetHandler(this->thread), EVENTIO_READ);
         }
       }
     }
diff --git a/iocore/net/UDPEventIO.cc b/iocore/net/UDPEventIO.cc
new file mode 100644
index 0000000000..2c55c0125a
--- /dev/null
+++ b/iocore/net/UDPEventIO.cc
@@ -0,0 +1,52 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "UDPEventIO.h"
+#include "P_UDPNet.h"
+
+int
+UDPEventIO::start(EventLoop l, UnixUDPConnection *uc, UDPNetHandler *uh, int 
events)
+{
+  _uc = uc;
+  _uh = uh;
+  return start_common(l, uc->fd, events);
+}
+
+void
+UDPEventIO::process_event(int flags)
+{
+  // TODO: handle EVENTIO_ERROR
+  if (flags & EVENTIO_READ) {
+    ink_assert(_uc && _uc->mutex && _uc->continuation);
+    ink_assert(_uc->refcount >= 1);
+    _uh->open_list.in_or_enqueue(_uc); // due to the above race
+    if (_uc->shouldDestroy()) {
+      _uh->open_list.remove(_uc);
+      _uc->Release();
+    } else {
+      udpNetInternal.udp_read_from_net(_uh, _uc);
+    }
+  } else {
+    Debug("iocore_udp_main", "Unhandled epoll event: 0x%04x", flags);
+  }
+}
diff --git a/iocore/net/UDPEventIO.h b/iocore/net/UDPEventIO.h
new file mode 100644
index 0000000000..b5623d3792
--- /dev/null
+++ b/iocore/net/UDPEventIO.h
@@ -0,0 +1,41 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include "EventIO.h"
+
+class UDPNetHandler;
+class UnixUDPConnection;
+
+class UDPEventIO : public EventIO
+{
+public:
+  UDPEventIO() : EventIO() {}
+  int start(EventLoop l, UnixUDPConnection *uc, UDPNetHandler *uh, int events);
+  void process_event(int flags) override;
+
+private:
+  UnixUDPConnection *_uc = nullptr;
+  UDPNetHandler *_uh     = nullptr;
+};
diff --git a/iocore/net/UnixNet.cc b/iocore/net/UnixNet.cc
index 0b33378cc6..f9529515e4 100644
--- a/iocore/net/UnixNet.cc
+++ b/iocore/net/UnixNet.cc
@@ -21,6 +21,7 @@
   limitations under the License.
  */
 
+#include "AsyncSignalEventIO.h"
 #include "P_Net.h"
 #include "P_UnixNet.h"
 #include "tscore/ink_hrtime.h"
@@ -44,13 +45,13 @@ const std::bitset<NetHandler::CONFIG_ITEM_COUNT> 
NetHandler::config_value_affect
 NetHandler *
 get_NetHandler(EThread *t)
 {
-  return (NetHandler *)ETHREAD_GET_PTR(t, unix_netProcessor.netHandler_offset);
+  return static_cast<NetHandler *>(ETHREAD_GET_PTR(t, 
unix_netProcessor.netHandler_offset));
 }
 
 PollCont *
 get_PollCont(EThread *t)
 {
-  return (PollCont *)ETHREAD_GET_PTR(t, unix_netProcessor.pollCont_offset);
+  return static_cast<PollCont *>(ETHREAD_GET_PTR(t, 
unix_netProcessor.pollCont_offset));
 }
 
 PollDescriptor *
@@ -174,17 +175,18 @@ initialize_thread_for_net(EThread *thread)
   thread->schedule_every(inactivityCop, HRTIME_SECONDS(cop_freq));
 
   thread->set_tail_handler(nh);
-  thread->ep = static_cast<EventIO *>(ats_malloc(sizeof(EventIO)));
-  new (thread->ep) EventIO();
-  thread->ep->type = EVENTIO_ASYNC_SIGNAL;
+
 #if HAVE_EVENTFD
-  thread->ep->start(pd, thread->evfd, nullptr, EVENTIO_READ);
+#if TS_USE_LINUX_IO_URING
+  auto ep = new IOUringEventIO();
+  ep->start(pd, IOUringContext::local_context());
 #else
-  thread->ep->start(pd, thread->evpipe[0], nullptr, EVENTIO_READ);
+  auto ep = new AsyncSignalEventIO();
+  ep->start(pd, thread->evfd, EVENTIO_READ);
 #endif
-
-#if TS_USE_LINUX_IO_URING
-  nh->uring_evio.type = EVENTIO_IO_URING;
-  nh->uring_evio.start(pd, 
IOUringContext::local_context()->register_eventfd(), nullptr, EVENTIO_READ);
+#else
+  auto ep = new AsyncSignalEventIO();
+  ep->start(pd, thread->evpipe[0], EVENTIO_READ);
 #endif
+  thread->ep = ep;
 }
diff --git a/iocore/net/UnixUDPNet.cc b/iocore/net/UnixUDPNet.cc
index 6f7ce146d4..20ced13e27 100644
--- a/iocore/net/UnixUDPNet.cc
+++ b/iocore/net/UnixUDPNet.cc
@@ -34,13 +34,17 @@
 #define __APPLE_USE_RFC_3542
 #endif
 
-#include "P_DNSConnection.h"
+#include "AsyncSignalEventIO.h"
+#include "I_AIO.h"
+#if TS_USE_LINUX_IO_URING
+#include "I_IO_URING.h"
+#endif
 #include "P_Net.h"
 #include "P_UDPNet.h"
 #include "tscore/ink_inet.h"
-
 #include "tscore/ink_sock.h"
 #include <netinet/udp.h>
+#include "P_UnixNet.h"
 
 #ifndef UDP_SEGMENT
 // This is needed because old glibc may not have the constant even if Kernel 
supports it.
@@ -253,14 +257,19 @@ initialize_thread_for_udp_net(EThread *thread)
   g_udp_numSendRetries = g_udp_numSendRetries < 0 ? 0 : g_udp_numSendRetries;
 
   thread->set_tail_handler(nh);
-  thread->ep = static_cast<EventIO *>(ats_malloc(sizeof(EventIO)));
-  new (thread->ep) EventIO();
-  thread->ep->type = EVENTIO_ASYNC_SIGNAL;
 #if HAVE_EVENTFD
-  thread->ep->start(upd, thread->evfd, nullptr, EVENTIO_READ);
+#if TS_USE_LINUX_IO_URING
+  auto ep = new IOUringEventIO();
+  ep->start(upd, IOUringContext::local_context());
 #else
-  thread->ep->start(upd, thread->evpipe[0], nullptr, EVENTIO_READ);
+  auto ep = new AsyncSignalEventIO();
+  ep->start(upd, thread->evfd, EVENTIO_READ);
 #endif
+#else
+  auto ep = new AsyncSignalEventIO();
+  ep->start(upd, thread->evpipe[0], EVENTIO_READ);
+#endif
+  thread->ep = ep;
 }
 
 EventType
@@ -1238,7 +1247,7 @@ UDPNetProcessor::UDPBind(Continuation *cont, sockaddr 
const *addr, int fd, int s
   pc = get_UDPPollCont(n->ethread);
   pd = pc->pollDescriptor;
 
-  n->ep.start(pd, n, EVENTIO_READ);
+  n->ep.start(pd, n, get_UDPNetHandler(cont->getThreadAffinity()), 
EVENTIO_READ);
 
   cont->handleEvent(NET_EVENT_DATAGRAM_OPEN, n);
   return ACTION_RESULT_DONE;
@@ -1696,18 +1705,6 @@ UDPQueue::SendMultipleUDPPackets(UDPPacket **p, uint16_t 
n)
 
 #undef LINK
 
-static void
-net_signal_hook_callback(EThread *thread)
-{
-#if HAVE_EVENTFD
-  uint64_t counter;
-  ATS_UNUSED_RETURN(read(thread->evfd, &counter, sizeof(uint64_t)));
-#else
-  char dummy[1024];
-  ATS_UNUSED_RETURN(read(thread->evpipe[0], &dummy[0], 1024));
-#endif
-}
-
 UDPNetHandler::UDPNetHandler(Cfg &&cfg) : udpOutQueue(cfg.enable_gso), 
_cfg{std::move(cfg)}
 {
   nextCheck = Thread::get_hrtime_updated() + HRTIME_MSECONDS(1000);
@@ -1778,34 +1775,9 @@ UDPNetHandler::waitForActivity(ink_hrtime timeout)
   int i        = 0;
   EventIO *epd = nullptr;
   for (i = 0; i < pc->pollDescriptor->result; i++) {
-    epd = static_cast<EventIO *> get_ev_data(pc->pollDescriptor, i);
-    if (epd->type == EVENTIO_UDP_CONNECTION) {
-      // TODO: handle EVENTIO_ERROR
-      if (get_ev_events(pc->pollDescriptor, i) & EVENTIO_READ) {
-        uc = epd->data.uc;
-        ink_assert(uc && uc->mutex && uc->continuation);
-        ink_assert(uc->refcount >= 1);
-        open_list.in_or_enqueue(uc); // due to the above race
-        if (uc->shouldDestroy()) {
-          open_list.remove(uc);
-          uc->Release();
-        } else {
-          udpNetInternal.udp_read_from_net(this, uc);
-        }
-      } else {
-        Debug("iocore_udp_main", "Unhandled epoll event: 0x%04x", 
get_ev_events(pc->pollDescriptor, i));
-      }
-    } else if (epd->type == EVENTIO_DNS_CONNECTION) {
-      // TODO: handle DNS conn if there is ET_UDP
-      if (epd->data.dnscon != nullptr) {
-        epd->data.dnscon->trigger();
-#if defined(USE_EDGE_TRIGGER)
-        epd->refresh(EVENTIO_READ);
-#endif
-      }
-    } else if (epd->type == EVENTIO_ASYNC_SIGNAL) {
-      net_signal_hook_callback(this->thread);
-    }
+    epd       = static_cast<EventIO *> get_ev_data(pc->pollDescriptor, i);
+    int flags = get_ev_events(pc->pollDescriptor, i);
+    epd->process_event(flags);
   } // end for
 
   // remove dead UDP connections


Reply via email to