Don't stop sending media on EWOULDBLOCK
This change makes WebRTC no longer stop sending video when we receive an EWOULDBLOCK error from the operating system. This was previously causing calls on a slow link (where the first hop is slow) to rapidly oscillate between starting and stopping video. We still do need to stop sending packets if there is no known good connection we can use for that. We used to generate a synthetic EWOULDBLOCK error in that case. This CL replaces it with a different code (ENOTCONN); EWOULDBLOCK no longer stops the stream but ENOTCONN does. I've updated all the places where we seemed to be generating EWOULDBLOCK for reasons other than some buffer been full; please give it a thorough look in case I missed something. R=pthatcher@webrtc.org Review URL: https://codereview.webrtc.org/2192963002 . Cr-Commit-Position: refs/heads/master@{#13566}
This commit is contained in:
parent
ec4f068bcd
commit
c309e0e3ea
@ -468,7 +468,7 @@ OpenSSLAdapter::Send(const void* pv, size_t cb) {
|
||||
|
||||
case SSL_WAIT:
|
||||
case SSL_CONNECTING:
|
||||
SetError(EWOULDBLOCK);
|
||||
SetError(ENOTCONN);
|
||||
return SOCKET_ERROR;
|
||||
|
||||
case SSL_CONNECTED:
|
||||
@ -534,7 +534,7 @@ int OpenSSLAdapter::Recv(void* pv, size_t cb, int64_t* timestamp) {
|
||||
|
||||
case SSL_WAIT:
|
||||
case SSL_CONNECTING:
|
||||
SetError(EWOULDBLOCK);
|
||||
SetError(ENOTCONN);
|
||||
return SOCKET_ERROR;
|
||||
|
||||
case SSL_CONNECTED:
|
||||
|
||||
@ -928,10 +928,10 @@ int P2PTransportChannel::SendPacket(const char *data, size_t len,
|
||||
error_ = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
// If we don't think the connection is working yet, return EWOULDBLOCK
|
||||
// If we don't think the connection is working yet, return ENOTCONN
|
||||
// instead of sending a packet that will probably be dropped.
|
||||
if (!ReadyToSend()) {
|
||||
error_ = EWOULDBLOCK;
|
||||
error_ = ENOTCONN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1292,7 +1292,7 @@ void P2PTransportChannel::SwitchSelectedConnection(Connection* conn) {
|
||||
<< selected_connection_->ToString();
|
||||
SignalRouteChange(this, selected_connection_->remote_candidate());
|
||||
// This is a temporary, but safe fix to webrtc issue 5705.
|
||||
// TODO(honghaiz): Make all EWOULDBLOCK error routed through the transport
|
||||
// TODO(honghaiz): Make all ENOTCONN error routed through the transport
|
||||
// channel so that it knows whether the media channel is allowed to
|
||||
// send; then it will only signal ready-to-send if the media channel
|
||||
// has been disallowed to send.
|
||||
|
||||
@ -341,7 +341,7 @@ class TestChannel : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
private:
|
||||
// ReadyToSend will only issue after a Connection recovers from EWOULDBLOCK.
|
||||
// ReadyToSend will only issue after a Connection recovers from ENOTCONN
|
||||
void OnConnectionReadyToSend(Connection* conn) {
|
||||
ASSERT_EQ(conn, conn_);
|
||||
connection_ready_to_send_ = true;
|
||||
@ -696,7 +696,7 @@ class PortTest : public testing::Test, public sigslot::has_slots<> {
|
||||
EXPECT_TRUE_WAIT(ch1.connection_ready_to_send(),
|
||||
kTcpReconnectTimeout);
|
||||
// Channel2 is the passive one so a new connection is created during
|
||||
// reconnect. This new connection should never have issued EWOULDBLOCK
|
||||
// reconnect. This new connection should never have issued ENOTCONN
|
||||
// hence the connection_ready_to_send() should be false.
|
||||
EXPECT_FALSE(ch2.connection_ready_to_send());
|
||||
} else {
|
||||
|
||||
@ -344,7 +344,7 @@ int RelayPort::SendTo(const void* data, size_t size,
|
||||
ASSERT(!entries_.empty());
|
||||
entry = entries_[0];
|
||||
if (!entry->connected()) {
|
||||
error_ = EWOULDBLOCK;
|
||||
error_ = ENOTCONN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,7 +348,7 @@ int TCPConnection::Send(const void* data, size_t size,
|
||||
// the connection a chance to reconnect.
|
||||
if (pretending_to_be_writable_ || write_state() != STATE_WRITABLE) {
|
||||
// TODO: Should STATE_WRITE_TIMEOUT return a non-blocking error?
|
||||
error_ = EWOULDBLOCK;
|
||||
error_ = ENOTCONN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
stats_.sent_total_packets++;
|
||||
|
||||
@ -518,7 +518,7 @@ int TurnPort::SendTo(const void* data, size_t size,
|
||||
}
|
||||
|
||||
if (!ready()) {
|
||||
error_ = EWOULDBLOCK;
|
||||
error_ = ENOTCONN;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -758,8 +758,8 @@ bool BaseChannel::SendPacket(bool rtcp,
|
||||
int ret = channel->SendPacket(packet->data<char>(), packet->size(),
|
||||
updated_options, flags);
|
||||
if (ret != static_cast<int>(packet->size())) {
|
||||
if (channel->GetError() == EWOULDBLOCK) {
|
||||
LOG(LS_WARNING) << "Got EWOULDBLOCK from socket.";
|
||||
if (channel->GetError() == ENOTCONN) {
|
||||
LOG(LS_WARNING) << "Got ENOTCONN from transport.";
|
||||
SetReadyToSend(rtcp, false);
|
||||
}
|
||||
return false;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user