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);
}