Skip to content

Commit 9b119c2

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 e93a1b2 commit 9b119c2

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

iocore/net/P_UnixNetState.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,14 @@ 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;
5455
int in_enabled_list;
5556
int triggered;
5657

57-
NetState() : enabled(0), vio(VIO::NONE), in_enabled_list(0), triggered(0) {}
58+
NetState() : enabled(0), error(0), vio(VIO::NONE), in_enabled_list(0), triggered(0) {}
5859
};
5960

6061
#endif

iocore/net/P_UnixNetVConnection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ class UnixNetVConnection : public NetVConnection
234234
virtual int64_t load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs);
235235
void readDisable(NetHandler *nh);
236236
void readSignalError(NetHandler *nh, int err);
237+
void writeSignalError(NetHandler *nh, int err);
237238
int readSignalDone(int event, NetHandler *nh);
238239
int readSignalAndUpdate(int event);
239240
void readReschedule(NetHandler *nh);

iocore/net/UnixNet.cc

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,13 @@ NetHandler::mainNetEvent(int event, Event *e)
450450
if (cop_list.in(vc)) {
451451
cop_list.remove(vc);
452452
}
453-
if (get_ev_events(pd, x) & (EVENTIO_READ | EVENTIO_ERROR)) {
453+
if (get_ev_events(pd, x) & EVENTIO_READ) {
454454
vc->read.triggered = 1;
455+
if (get_ev_events(pd, x) & EVENTIO_ERROR) {
456+
vc->read.error = 1;
457+
} else {
458+
vc->read.error = 0;
459+
}
455460
if (!read_ready_list.in(vc)) {
456461
read_ready_list.enqueue(vc);
457462
} else if (get_ev_events(pd, x) & EVENTIO_ERROR) {
@@ -461,8 +466,13 @@ NetHandler::mainNetEvent(int event, Event *e)
461466
}
462467
}
463468
vc = epd->data.vc;
464-
if (get_ev_events(pd, x) & (EVENTIO_WRITE | EVENTIO_ERROR)) {
469+
if (get_ev_events(pd, x) & EVENTIO_WRITE) {
465470
vc->write.triggered = 1;
471+
if (get_ev_events(pd, x) & EVENTIO_ERROR) {
472+
vc->write.error = 1;
473+
} else {
474+
vc->write.error = 0;
475+
}
466476
if (!write_ready_list.in(vc)) {
467477
write_ready_list.enqueue(vc);
468478
} else if (get_ev_events(pd, x) & EVENTIO_ERROR) {
@@ -495,7 +505,7 @@ NetHandler::mainNetEvent(int event, Event *e)
495505
set_cont_flags(vc->control_flags);
496506
if (vc->closed)
497507
close_UnixNetVConnection(vc, trigger_event->ethread);
498-
else if (vc->read.enabled && vc->read.triggered)
508+
else if ((vc->read.enabled || vc->read.error) && vc->read.triggered)
499509
vc->net_read_io(this, trigger_event->ethread);
500510
else if (!vc->read.enabled) {
501511
read_ready_list.remove(vc);
@@ -512,7 +522,7 @@ NetHandler::mainNetEvent(int event, Event *e)
512522
set_cont_flags(vc->control_flags);
513523
if (vc->closed)
514524
close_UnixNetVConnection(vc, trigger_event->ethread);
515-
else if (vc->write.enabled && vc->write.triggered)
525+
else if ((vc->write.enabled || vc->write.error) && vc->write.triggered)
516526
write_to_net(this, vc, trigger_event->ethread);
517527
else if (!vc->write.enabled) {
518528
write_ready_list.remove(vc);
@@ -530,7 +540,7 @@ NetHandler::mainNetEvent(int event, Event *e)
530540
diags->set_override(vc->control.debug_override);
531541
if (vc->closed)
532542
close_UnixNetVConnection(vc, trigger_event->ethread);
533-
else if (vc->read.enabled && vc->read.triggered)
543+
else if ((vc->read.enabled || vc->read.error) && vc->read.triggered)
534544
vc->net_read_io(this, trigger_event->ethread);
535545
else if (!vc->read.enabled)
536546
vc->ep.modify(-EVENTIO_READ);
@@ -539,7 +549,7 @@ NetHandler::mainNetEvent(int event, Event *e)
539549
diags->set_override(vc->control.debug_override);
540550
if (vc->closed)
541551
close_UnixNetVConnection(vc, trigger_event->ethread);
542-
else if (vc->write.enabled && vc->write.triggered)
552+
else if ((vc->write.enabled || vc->write.error) && vc->write.triggered)
543553
write_to_net(this, vc, trigger_event->ethread);
544554
else if (!vc->write.enabled)
545555
vc->ep.modify(-EVENTIO_WRITE);

iocore/net/UnixNetVConnection.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,19 @@ read_from_net(NetHandler *nh, UnixNetVConnection *vc, EThread *thread)
260260
close_UnixNetVConnection(vc, thread);
261261
return;
262262
}
263+
264+
if (!s->enabled && vc->read.error) {
265+
int err = 0, errlen = sizeof(int);
266+
if (getsockopt(vc->con.fd, SOL_SOCKET, SO_ERROR, &err, (socklen_t *)&errlen) == -1) {
267+
err = errno;
268+
}
269+
// if it is a non-temporary error, we should die appropriately
270+
if (err && err != EAGAIN && err != EINTR) {
271+
read_signal_error(nh, vc, err);
272+
return;
273+
}
274+
}
275+
263276
// if it is not enabled.
264277
if (!s->enabled || s->vio.op != VIO::READ) {
265278
read_disable(nh, vc);
@@ -427,6 +440,17 @@ write_to_net_io(NetHandler *nh, UnixNetVConnection *vc, EThread *thread)
427440
return;
428441
}
429442

443+
if (!s->enabled && vc->write.error) {
444+
int err = 0, errlen = sizeof(int);
445+
if (getsockopt(vc->con.fd, SOL_SOCKET, SO_ERROR, &err, (socklen_t *)&errlen) == -1) {
446+
err = errno;
447+
}
448+
if (err && err != EAGAIN && err != EINTR) {
449+
write_signal_error(nh, vc, err);
450+
return;
451+
}
452+
}
453+
430454
// This function will always return true unless
431455
// vc is an SSLNetVConnection.
432456
if (!vc->getSSLHandShakeComplete()) {
@@ -1079,6 +1103,12 @@ UnixNetVConnection::readSignalError(NetHandler *nh, int err)
10791103
read_signal_error(nh, this, err);
10801104
}
10811105

1106+
void
1107+
UnixNetVConnection::writeSignalError(NetHandler *nh, int err)
1108+
{
1109+
write_signal_error(nh, this, err);
1110+
}
1111+
10821112
int
10831113
UnixNetVConnection::readSignalDone(int event, NetHandler *nh)
10841114
{

0 commit comments

Comments
 (0)