You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2010/01/09 22:36:20 UTC

svn commit: r897556 - in /incubator/trafficserver/traffic/branches/dev/iocore/net: P_UnixNet.h UnixNet.cc UnixNetVConnection.cc

Author: jplevyak
Date: Sat Jan  9 21:36:20 2010
New Revision: 897556

URL: http://svn.apache.org/viewvc?rev=897556&view=rev
Log:
TS-50: prevent spinning when libev is used with keep-alive connections

Modified:
    incubator/trafficserver/traffic/branches/dev/iocore/net/P_UnixNet.h
    incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNet.cc
    incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNetVConnection.cc

Modified: incubator/trafficserver/traffic/branches/dev/iocore/net/P_UnixNet.h
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/iocore/net/P_UnixNet.h?rev=897556&r1=897555&r2=897556&view=diff
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/iocore/net/P_UnixNet.h (original)
+++ incubator/trafficserver/traffic/branches/dev/iocore/net/P_UnixNet.h Sat Jan  9 21:36:20 2010
@@ -51,6 +51,7 @@
 #include "ev_vars.h"
 #undef VAR
 };
+extern "C" void fd_change(struct ev_loop *, int fd, int flags);
 #endif
 
 class PollDescriptor;
@@ -82,6 +83,11 @@
   int start(EventLoop l, UnixNetVConnection *vc, int events);
   int start(EventLoop l, UnixUDPConnection *vc, int events);
   int start(EventLoop l, int fd, Continuation *c, int events);
+  /*
+    Change the existing events by adding modify(EVENTIO_READ)
+    or removing modify(-EVENTIO_READ)
+  */
+  int modify(int events);
   int stop();
   int close();
   EventIO() { 
@@ -218,6 +224,9 @@
   ASLL(UnixNetVConnection, read.enable_link) read_enable_list;
   ASLL(UnixNetVConnection, write.enable_link) write_enable_list;
 
+  time_t sec;
+  int cycles;
+
   int startNetEvent(int event, Event * data);
   int mainNetEvent(int event, Event * data);
   int mainNetEventExt(int event, Event * data);
@@ -432,6 +441,7 @@
 #endif
   vc->read.enabled = 0;
   nh->read_ready_list.remove(vc);
+  vc->ep.modify(-EVENTIO_READ);
 }
 
 static inline void
@@ -451,6 +461,7 @@
 #endif
   vc->write.enabled = 0;
   nh->write_ready_list.remove(vc);
+  vc->ep.modify(-EVENTIO_WRITE);
 }
 
 inline int EventIO::start(EventLoop l, DNSConnection *vc, int events) {
@@ -491,6 +502,20 @@
   return 0;
 }
 
+inline int EventIO::modify(int e) {
+  ink_assert(event_loop);
+  int ee = eio.events;
+  if (e < 0)
+    ee &= ~(-e);
+  else
+    ee |= e;
+  if (ee != eio.events) {
+    eio.events = ee;
+    fd_change(event_loop->eio, eio.fd, 0);
+  }
+  return 0;
+}
+
 inline int EventIO::stop() {
   if (event_loop) {
     ev_io_stop(event_loop->eio, &eio);
@@ -512,14 +537,19 @@
   ev.data.ptr = this;
   return epoll_ctl(event_loop->epoll_fd, EPOLL_CTL_ADD, fd, &ev);
 #elif defined(USE_KQUEUE)
-    struct kevent ev;
-    EV_SET(&ev, con[icon].fd, EVFILT_READ, EV_ADD, 0, 0, con[icon].epoll_ptr);
-    r = kevent(pd->kqueue_fd, &ev, 1, NULL, 0, NULL);
+  struct kevent ev;
+  EV_SET(&ev, con[icon].fd, EVFILT_READ, EV_ADD, 0, 0, con[icon].epoll_ptr);
+  return kevent(pd->kqueue_fd, &ev, 1, NULL, 0, NULL);
 #else
 #error port me
 #endif
 }
 
+inline int EventIO::modify(int e) {
+  (void)e;
+  return 0;
+}
+
 inline int EventIO::stop() {
   if (event_loop) {
 #if defined(USE_EPOLL)
@@ -531,7 +561,7 @@
     struct kevent ev[2];
     EV_SET(&ev[0], con[icon].fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
     EV_SET(&ev[1], con[icon].fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
-    kevent(pd->kqueue_fd, &ev[0], 2, NULL, 0, NULL);
+    return kevent(pd->kqueue_fd, &ev[0], 2, NULL, 0, NULL);
 #else
 #error port me
 #endif

Modified: incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNet.cc
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNet.cc?rev=897556&r1=897555&r2=897556&view=diff
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNet.cc (original)
+++ incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNet.cc Sat Jan  9 21:36:20 2010
@@ -170,6 +170,7 @@
 
   SList(UnixNetVConnection, read.enable_link) rq(nh->read_enable_list.popall());
   while ((vc = rq.pop())) {
+    vc->ep.modify(EVENTIO_READ);
     vc->read.in_enabled_list = 0;
     if ((vc->read.enabled && vc->read.triggered) || vc->closed)
       nh->read_ready_list.in_or_enqueue(vc);
@@ -177,6 +178,7 @@
 
   SList(UnixNetVConnection, write.enable_link) wq(nh->write_enable_list.popall());
   while ((vc = wq.pop())) {
+    vc->ep.modify(EVENTIO_WRITE);
     vc->write.in_enabled_list = 0;
     if ((vc->write.enabled && vc->write.triggered) || vc->closed)
       nh->write_ready_list.in_or_enqueue(vc);
@@ -236,7 +238,7 @@
       if (get_ev_events(pd,x) & (EVENTIO_READ)) {
         vc->read.triggered = 1;
         vc->addLogMessage("read triggered");
-        if ((vc->read.enabled || vc->closed) && !read_ready_list.in(vc))
+        if (!read_ready_list.in(vc))
           read_ready_list.enqueue(vc);
         else if (get_ev_events(pd,x) & EVENTIO_ERROR) {
           // check for unhandled epoll events that should be handled
@@ -248,7 +250,7 @@
       if (get_ev_events(pd,x) & EVENTIO_WRITE) {
         vc->write.triggered = 1;
         vc->addLogMessage("write triggered");
-        if ((vc->write.enabled || vc->closed) && !write_ready_list.in(vc))
+        if (!write_ready_list.in(vc))
           write_ready_list.enqueue(vc);
         else if (get_ev_events(pd,x) & EVENTIO_ERROR) {
           // check for unhandled epoll events that should be handled
@@ -268,27 +270,55 @@
 
   pd->result = 0;
 
+#if !defined(USE_LIBEV) && defined(USE_EPOLL) && defined(USE_EDGE_TRIGGER_EPOLL)
   UnixNetVConnection *next_vc = NULL;
   vc = read_ready_list.head;
   while (vc) {
     next_vc = vc->read.ready_link.next;
+#else
+  while ((vc = read_ready_list.dequeue())) {
+#endif
     if (vc->closed)
       close_UnixNetVConnection(vc, trigger_event->ethread);
     else if (vc->read.enabled && vc->read.triggered)
       vc->net_read_io(this, trigger_event->ethread);
+    else if (!vc->read.enabled)
+#if !defined(USE_LIBEV) && defined(USE_EPOLL) && defined(USE_EDGE_TRIGGER_EPOLL)
+      read_ready_list.remove(vc);
+#else
+      vc->ep.modify(-EVENTIO_READ);
+#endif
+#if defined(USE_EPOLL) && defined(USE_EDGE_TRIGGER_EPOLL)
     vc = next_vc;
   }
+#else
+  }
+#endif
 
+#if !defined(USE_LIBEV) && defined(USE_EPOLL) && defined(USE_EDGE_TRIGGER_EPOLL)
   next_vc = NULL;
   vc = write_ready_list.head;
   while (vc) {
     next_vc = vc->write.ready_link.next;
+#else
+  while ((vc = write_ready_list.dequeue())) {
+#endif
     if (vc->closed)
       close_UnixNetVConnection(vc, trigger_event->ethread);
     else if (vc->write.enabled && vc->write.triggered)
       write_to_net(this, vc, pd, trigger_event->ethread);
+    else if (!vc->write.enabled)
+#if !defined(USE_LIBEV) && defined(USE_EPOLL) && defined(USE_EDGE_TRIGGER_EPOLL)
+      write_ready_list.remove(vc);
+#else
+      vc->ep.modify(-EVENTIO_WRITE);
+#endif
+#if defined(USE_EPOLL) && defined(USE_EDGE_TRIGGER_EPOLL)
     vc = next_vc;
   }
+#else
+  }
+#endif
 
   return EVENT_CONT;
 }

Modified: incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNetVConnection.cc
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNetVConnection.cc?rev=897556&r1=897555&r2=897556&view=diff
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNetVConnection.cc (original)
+++ incubator/trafficserver/traffic/branches/dev/iocore/net/UnixNetVConnection.cc Sat Jan  9 21:36:20 2010
@@ -710,11 +710,13 @@
   ink_debug_assert(t == this_ethread());
   if (nh->mutex->thread_holding == t) {
     if (vio == &read.vio) {
+      ep.modify(EVENTIO_READ);
       if (read.triggered)
         nh->read_ready_list.in_or_enqueue(this);
       else
         nh->read_ready_list.remove(this);
     } else {
+      ep.modify(EVENTIO_WRITE);
       if (write.triggered)
         nh->write_ready_list.in_or_enqueue(this);
       else
@@ -736,11 +738,13 @@
       }
     } else {
       if (vio == &read.vio) {
+        ep.modify(EVENTIO_READ);
         if (read.triggered)
           nh->read_ready_list.in_or_enqueue(this);
         else
           nh->read_ready_list.remove(this);
       } else {
+        ep.modify(EVENTIO_WRITE);
         if (write.triggered)
           nh->write_ready_list.in_or_enqueue(this);
         else
@@ -753,24 +757,27 @@
 void
 UnixNetVConnection::reenable_re(VIO * vio)
 {
-  set_enabled(vio);
   if (!thread)
     return;
   EThread *t = vio->mutex->thread_holding;
   ink_debug_assert(t == this_ethread());
   if (nh->mutex->thread_holding == t) {
+    set_enabled(vio);
     if (vio == &read.vio) {
+      ep.modify(EVENTIO_READ);
       if (read.triggered)
         net_read_io(nh, t);
       else
         nh->read_ready_list.remove(this);
     } else {
+      ep.modify(EVENTIO_WRITE);
       if (write.triggered)
         write_to_net(nh, this, NULL, t);
       else
         nh->write_ready_list.remove(this);
     }
-  }
+  } else
+    reenable(vio);
 }