Skip to content

Commit 84934a8

Browse files
committed
TS-4796 Change UnixNetHandler to always bubble up epoll errors to the VConnection
Before if the vcon wasn't read or write enabled errors would be swallowed. This leads to a variety of issues where the socket errors aren't dealt with immediately.
1 parent b5bf7c9 commit 84934a8

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

iocore/net/P_UnixNetState.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class UnixNetVConnection;
4848

4949
struct NetState {
5050
volatile int enabled;
51+
volatile int error;
5152
VIO vio;
5253
Link<UnixNetVConnection> ready_link;
5354
SLink<UnixNetVConnection> enable_link;

iocore/net/P_UnixNetVConnection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ class UnixNetVConnection : public NetVConnection
215215
virtual int64_t load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs);
216216
void readDisable(NetHandler *nh);
217217
void readSignalError(NetHandler *nh, int err);
218+
void writeSignalError(NetHandler *nh, int err);
218219
int readSignalDone(int event, NetHandler *nh);
219220
int readSignalAndUpdate(int event);
220221
void readReschedule(NetHandler *nh);

iocore/net/UnixNet.cc

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,9 @@ NetHandler::mainNetEvent(int event, Event *e)
480480
vc = epd->data.vc;
481481
if (get_ev_events(pd, x) & (EVENTIO_READ | EVENTIO_ERROR)) {
482482
vc->read.triggered = 1;
483+
if (get_ev_events(pd, x) & EVENTIO_ERROR) {
484+
vc->read.error = 1;
485+
}
483486
if (!read_ready_list.in(vc)) {
484487
read_ready_list.enqueue(vc);
485488
} else if (get_ev_events(pd, x) & EVENTIO_ERROR) {
@@ -491,6 +494,9 @@ NetHandler::mainNetEvent(int event, Event *e)
491494
vc = epd->data.vc;
492495
if (get_ev_events(pd, x) & (EVENTIO_WRITE | EVENTIO_ERROR)) {
493496
vc->write.triggered = 1;
497+
if (get_ev_events(pd, x) & EVENTIO_ERROR) {
498+
vc->write.error = 1;
499+
}
494500
if (!write_ready_list.in(vc)) {
495501
write_ready_list.enqueue(vc);
496502
} else if (get_ev_events(pd, x) & EVENTIO_ERROR) {
@@ -525,7 +531,17 @@ NetHandler::mainNetEvent(int event, Event *e)
525531
close_UnixNetVConnection(vc, trigger_event->ethread);
526532
else if (vc->read.enabled && vc->read.triggered)
527533
vc->net_read_io(this, trigger_event->ethread);
528-
else if (!vc->read.enabled) {
534+
else if (vc->read.error) {
535+
int err = 0, errlen = sizeof(int);
536+
if (getsockopt(vc->con.fd, SOL_SOCKET, SO_ERROR, &err, (socklen_t *)&errlen) == -1) {
537+
err = errno;
538+
}
539+
if (err != EAGAIN && err != EINTR) {
540+
vc->readSignalError(this, err);
541+
} else {
542+
vc->read.error = 0;
543+
}
544+
} else if (!vc->read.enabled) {
529545
read_ready_list.remove(vc);
530546
#if defined(solaris)
531547
if (vc->read.triggered && vc->write.enabled) {
@@ -542,7 +558,17 @@ NetHandler::mainNetEvent(int event, Event *e)
542558
close_UnixNetVConnection(vc, trigger_event->ethread);
543559
else if (vc->write.enabled && vc->write.triggered)
544560
write_to_net(this, vc, trigger_event->ethread);
545-
else if (!vc->write.enabled) {
561+
else if (vc->write.error) {
562+
int err = 0, errlen = sizeof(int);
563+
if (getsockopt(vc->con.fd, SOL_SOCKET, SO_ERROR, &err, (socklen_t *)&errlen) == -1) {
564+
err = errno;
565+
}
566+
if (err != EAGAIN && err != EINTR) {
567+
vc->writeSignalError(this, err);
568+
} else {
569+
vc->write.error = 0;
570+
}
571+
} else if (!vc->write.enabled) {
546572
write_ready_list.remove(vc);
547573
#if defined(solaris)
548574
if (vc->write.triggered && vc->read.enabled) {

iocore/net/UnixNetVConnection.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,12 @@ UnixNetVConnection::readSignalError(NetHandler *nh, int err)
10241024
read_signal_error(nh, this, err);
10251025
}
10261026

1027+
void
1028+
UnixNetVConnection::writeSignalError(NetHandler *nh, int err)
1029+
{
1030+
write_signal_error(nh, this, err);
1031+
}
1032+
10271033
int
10281034
UnixNetVConnection::readSignalDone(int event, NetHandler *nh)
10291035
{

0 commit comments

Comments
 (0)