aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2019-02-18 20:21:14 +0100
committerLukas Larsson <[email protected]>2019-02-18 20:33:52 +0100
commitfccaf185f657cbbfd61dc2104bf220f5396a2078 (patch)
tree9ef0136342a163c3bae8bf04fbc74d99d521d722 /erts
parent5548b539bbf75f17a178a8352d56d80a5218c6b2 (diff)
downloadotp-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')
-rw-r--r--erts/emulator/drivers/common/inet_drv.c22
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;
}