aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2018-10-10 16:19:02 +0200
committerLukas Larsson <[email protected]>2018-12-03 13:34:05 +0100
commita2d9a51091578da0ef41fbd91b281091d20aca2b (patch)
tree7b2c7cebc766911e1f5b308e2c6c4162f1a003d3
parentd4440ce1793638f8daca35a32936d3005cc3be7a (diff)
downloadotp-a2d9a51091578da0ef41fbd91b281091d20aca2b.tar.gz
otp-a2d9a51091578da0ef41fbd91b281091d20aca2b.tar.bz2
otp-a2d9a51091578da0ef41fbd91b281091d20aca2b.zip
erts: Implement delay_send using timer instead of poll
The previous implementation uses a round-trip in the poll-set to simulate a yield of the port context. With the poll thread implementation this is no longer a good idea as it generated a lot more work for the system. So this commit changes the implementation to use a timer instead. OTP-15471
-rw-r--r--erts/emulator/drivers/common/inet_drv.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 8a7cb7e6fa..627e1c8ec2 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -11250,6 +11250,12 @@ static int tcp_shutdown_error(tcp_descriptor* desc, int err)
return tcp_send_or_shutdown_error(desc, err);
}
+static void tcp_inet_delay_send(ErlDrvData data, ErlDrvTermData dummy)
+{
+ tcp_descriptor *desc = (tcp_descriptor*)data;
+ (void)tcp_inet_output(desc, INETP(desc)->s);
+}
+
/*
** Send non-blocking vector data
*/
@@ -11319,7 +11325,10 @@ static int tcp_sendv(tcp_descriptor* desc, ErlIOVec* ev)
INETP(desc)->is_ignored |= INET_IGNORE_WRITE;
n = 0;
} else if (desc->tcp_add_flags & TCP_ADDF_DELAY_SEND) {
- n = 0;
+ driver_enqv(ix, ev, 0);
+ add_multi_timer(desc, INETP(desc)->port, 0,
+ 0, &tcp_inet_delay_send);
+ return 0;
} else if (IS_SOCKET_ERROR(sock_sendv(desc->inet.s, ev->iov,
vsize, &n, 0))) {
if ((sock_errno() != ERRNO_BLOCK) && (sock_errno() != EINTR)) {
@@ -11816,6 +11825,12 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event)
#ifdef __WIN32__
desc->inet.send_would_block = 1;
#endif
+ /* If DELAY_SEND is set ready_output may have
+ been called without doing select so we do
+ a select in order to get into the correct
+ state */
+ if (desc->tcp_add_flags & TCP_ADDF_DELAY_SEND)
+ sock_select(INETP(desc), FD_WRITE, 1);
goto done;
} else if (n == 0) { /* Workaround for redhat/CentOS 6.3 returning
0 when sending packets with
@@ -12962,9 +12977,6 @@ static MultiTimerData *add_multi_timer(tcp_descriptor *desc, ErlDrvPort port,
}
/* Possibly set new timer */
if (!s) {
- if (mtd->next) {
- driver_cancel_timer(port);
- }
driver_set_timer(port,timeout);
}
return mtd;