Fix a SCTP message reordering issue in datachannel.cc.

Previously DataChannel::SendQueuedDataMessages continues the loop of sending queued messages if the channel is blocked, which will cause message reordering if the channel becomes unblocked during the loop, i.e. messages attempted after the unblocking will be sent earlier than the older messages attempted before the unblocking.

BUG=3979
R=pthatcher@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/25149004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7690 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
jiayl@webrtc.org 2014-11-12 17:28:40 +00:00
parent ea73ff7267
commit 6ca6190be2
2 changed files with 28 additions and 16 deletions

View File

@ -215,7 +215,7 @@ bool DataChannel::Send(const DataBuffer& buffer) {
return true;
}
bool success = SendDataMessage(buffer);
bool success = SendDataMessage(buffer, true);
if (data_channel_type_ == cricket::DCT_RTP) {
return success;
}
@ -461,17 +461,17 @@ void DataChannel::DeliverQueuedReceivedData() {
void DataChannel::SendQueuedDataMessages() {
ASSERT(was_ever_writable_ && state_ == kOpen);
PacketQueue packet_buffer;
packet_buffer.Swap(&queued_send_data_);
while (!packet_buffer.Empty()) {
rtc::scoped_ptr<DataBuffer> buffer(packet_buffer.Front());
SendDataMessage(*buffer);
packet_buffer.Pop();
while (!queued_send_data_.Empty()) {
rtc::scoped_ptr<DataBuffer> buffer(queued_send_data_.Front());
if (!SendDataMessage(*buffer, false)) {
break;
}
queued_send_data_.Pop();
}
}
bool DataChannel::SendDataMessage(const DataBuffer& buffer) {
bool DataChannel::SendDataMessage(const DataBuffer& buffer,
bool queue_if_blocked) {
cricket::SendDataParams send_params;
if (data_channel_type_ == cricket::DCT_SCTP) {
@ -494,14 +494,26 @@ bool DataChannel::SendDataMessage(const DataBuffer& buffer) {
cricket::SendDataResult send_result = cricket::SDR_SUCCESS;
bool success = provider_->SendData(send_params, buffer.data, &send_result);
if (!success && data_channel_type_ == cricket::DCT_SCTP) {
if (send_result != cricket::SDR_BLOCK || !QueueSendDataMessage(buffer)) {
LOG(LS_ERROR) << "Closing the DataChannel due to a failure to send data, "
<< "send_result = " << send_result;
Close();
if (success) {
return true;
}
if (data_channel_type_ != cricket::DCT_SCTP) {
return false;
}
if (send_result == cricket::SDR_BLOCK) {
if (!queue_if_blocked || QueueSendDataMessage(buffer)) {
return false;
}
}
return success;
// Close the channel if the error is not SDR_BLOCK, or if queuing the
// message failed.
LOG(LS_ERROR) << "Closing the DataChannel due to a failure to send data, "
<< "send_result = " << send_result;
Close();
return false;
}
bool DataChannel::QueueSendDataMessage(const DataBuffer& buffer) {

View File

@ -213,7 +213,7 @@ class DataChannel : public DataChannelInterface,
void DeliverQueuedReceivedData();
void SendQueuedDataMessages();
bool SendDataMessage(const DataBuffer& buffer);
bool SendDataMessage(const DataBuffer& buffer, bool queue_if_blocked);
bool QueueSendDataMessage(const DataBuffer& buffer);
void SendQueuedControlMessages();