summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2014-12-15 23:35:13 +0000
committerPhilip Withnall <philip.withnall@collabora.co.uk>2014-12-17 08:30:46 +0000
commit8ecd6b89a815856b52d5931dd3a6d90fa9e85757 (patch)
tree151eb073995f2ec4afc9ae2b9694d282dbb54d6b
parent49f0f8f7e65ff816775387b5a33b27565beaf3f5 (diff)
agent: Handle EWOULDBLOCK when transmitting pseudo-TCP segments
The pseudo-TCP code previously didn’t handle EAGAIN or EWOULDBLOCK errors from the low-level NiceSocket code. This caused pseudo-TCP connections to be dropped if the transmitting socket ever filled up, which could cause problems on high bandwidth connections. Fix the issue by effectively dropping the packet on EWOULDBLOCK. This will eventually get picked up by the pseudo-TCP recovery mechanism, retransmitting the packet and throttling the sender. This should hopefully reduce the system resource usage which caused EWOULDBLOCK in the first place. Spotted and debugged by Radosław Kołodziejczyk <radek.kolodziejczyk@gmail.com>. https://bugs.freedesktop.org/show_bug.cgi?id=87344
-rw-r--r--agent/agent.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/agent/agent.c b/agent/agent.c
index a2fd46d..c0efd76 100644
--- a/agent/agent.c
+++ b/agent/agent.c
@@ -1754,8 +1754,15 @@ pseudo_tcp_socket_write_packet (PseudoTcpSocket *psocket,
nice_address_get_port (addr));
}
- if (nice_socket_send (sock, addr, len, buffer))
+ /* Send the segment. nice_socket_send() returns 0 on EWOULDBLOCK; in that
+ * case the segment is not sent on the wire, but we return WR_SUCCESS
+ * anyway. This effectively drops the segment. The pseudo-TCP state machine
+ * will eventually pick up this loss and go into recovery mode, reducing
+ * its transmission rate and, hopefully, the usage of system resources
+ * which caused the EWOULDBLOCK in the first place. */
+ if (nice_socket_send (sock, addr, len, buffer) >= 0) {
return WR_SUCCESS;
+ }
} else {
nice_debug ("%s: WARNING: Failed to send pseudo-TCP packet from agent %p "
"as no pair has been selected yet.", G_STRFUNC, component->agent);