diff options
author | Lukas Larsson <[email protected]> | 2018-10-10 16:19:02 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2018-12-03 13:34:05 +0100 |
commit | a2d9a51091578da0ef41fbd91b281091d20aca2b (patch) | |
tree | 7b2c7cebc766911e1f5b308e2c6c4162f1a003d3 /erts | |
parent | d4440ce1793638f8daca35a32936d3005cc3be7a (diff) | |
download | otp-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
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/drivers/common/inet_drv.c | 20 |
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; |