diff options
author | Lukas Larsson <[email protected]> | 2019-02-18 20:21:14 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2019-02-18 20:33:52 +0100 |
commit | fccaf185f657cbbfd61dc2104bf220f5396a2078 (patch) | |
tree | 9ef0136342a163c3bae8bf04fbc74d99d521d722 /erts/emulator/drivers/common/inet_drv.c | |
parent | 5548b539bbf75f17a178a8352d56d80a5218c6b2 (diff) | |
download | otp-fccaf185f657cbbfd61dc2104bf220f5396a2078.tar.gz otp-fccaf185f657cbbfd61dc2104bf220f5396a2078.tar.bz2 otp-fccaf185f657cbbfd61dc2104bf220f5396a2078.zip |
erts: Add yield via timeout to inet read_packet
The idea here is that the timeout of 0 will work like a yield
so that that we don't starve other ports/processes, but it
is faster than the select trigger. We don't deselect on the socket
because it does not matter if it is triggered laster or not
as we'll just get an EAGAIN.
Doing this also circumvents the fact that no select is done on
active true style sockets until all I/O has been handled. So in
a system with a lot of active true style I/O this will could be
very benificial.
Diffstat (limited to 'erts/emulator/drivers/common/inet_drv.c')
-rw-r--r-- | erts/emulator/drivers/common/inet_drv.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index a1abeb9cbb..49ce0c7600 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -6772,8 +6772,12 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) if ( ((desc->stype == SOCK_STREAM) && IS_CONNECTED(desc)) || ((desc->stype == SOCK_DGRAM) && IS_OPEN(desc))) { - if (desc->active != old_active) + if (desc->active != old_active) { + /* Need to cancel the read_packet timer if we go from active to passive. */ + if (desc->active == INET_PASSIVE && desc->stype == SOCK_DGRAM) + driver_cancel_timer(desc->port); sock_select(desc, (FD_READ|FD_CLOSE), (desc->active>0)); + } /* XXX: UDP sockets could also trigger immediate read here NIY */ if ((desc->stype==SOCK_STREAM) && desc->active) { @@ -12539,9 +12543,12 @@ static void packet_inet_timeout(ErlDrvData e) { udp_descriptor * udesc = (udp_descriptor*) e; inet_descriptor * desc = INETP(udesc); - if (!(desc->active)) + if (!(desc->active)) { sock_select(desc, FD_READ, 0); - async_error_am (desc, am_timeout); + async_error_am (desc, am_timeout); + } else { + (void)packet_inet_input(udesc, desc->s); + } } @@ -12897,6 +12904,15 @@ static int packet_inet_input(udp_descriptor* udesc, HANDLE event) sock_select(desc, FD_READ, 1); } #endif + + /* We set a timer on the port to trigger now. + This emulates a "yield" operation as that is + what we want to do here. We do *NOT* do a deselect + as that is expensive, instead we check if the + socket it still active when the timeout triggers + and if it is not, then we just ignore the timeout */ + driver_set_timer(desc->port, 0); + return count; } |