Index: net/dns/mdns_client_impl.cc |
diff --git a/net/dns/mdns_client_impl.cc b/net/dns/mdns_client_impl.cc |
index 1745385784a8ec4ba1f6e1b420fa877f7b190d7f..5880a3be7b67fc65e0fe8a89d0284842166f37a7 100644 |
--- a/net/dns/mdns_client_impl.cc |
+++ b/net/dns/mdns_client_impl.cc |
@@ -4,6 +4,8 @@ |
#include "net/dns/mdns_client_impl.h" |
+#include <queue> |
+ |
#include "base/bind.h" |
#include "base/message_loop/message_loop_proxy.h" |
#include "base/stl_util.h" |
@@ -54,7 +56,8 @@ MDnsConnection::SocketHandler::SocketHandler( |
MDnsConnection* connection) |
: socket_(socket.Pass()), |
connection_(connection), |
- response_(dns_protocol::kMaxMulticastSize) { |
+ response_(dns_protocol::kMaxMulticastSize), |
+ send_in_progress_(false) { |
} |
MDnsConnection::SocketHandler::~SocketHandler() { |
@@ -98,14 +101,37 @@ void MDnsConnection::SocketHandler::OnDatagramReceived(int rv) { |
connection_->OnError(this, rv); |
} |
-int MDnsConnection::SocketHandler::Send(IOBuffer* buffer, unsigned size) { |
- return socket_->SendTo(buffer, size, multicast_addr_, |
- base::Bind(&MDnsConnection::SocketHandler::SendDone, |
- base::Unretained(this) )); |
+void MDnsConnection::SocketHandler::Send( |
+ const scoped_refptr<IOBufferWithSize>& buffer) { |
+ if (send_in_progress_) { |
+ send_queue_.push(buffer); |
+ return; |
+ } |
+ int rv = socket_->SendTo(buffer.get(), |
+ buffer->size(), |
+ multicast_addr_, |
+ base::Bind(&MDnsConnection::SocketHandler::SendDone, |
+ base::Unretained(this))); |
+ if (rv == ERR_IO_PENDING) { |
+ send_in_progress_ = true; |
+ return; |
Sergey Ulanov
2014/09/19 21:11:27
Maybe remove return and use else below.
Vitaly Buka (NO REVIEWS)
2014/09/19 21:33:27
Done.
|
+ } |
+ if (rv < OK) |
+ connection_->OnError(this, rv); |
} |
void MDnsConnection::SocketHandler::SendDone(int rv) { |
- // TODO(noamsml): Retry logic. |
+ DCHECK(send_in_progress_); |
+ if (rv == ERR_IO_PENDING) |
Vitaly Buka (NO REVIEWS)
2014/09/19 21:04:46
Looks like in both implementations ERR_IO_PENDING
|
+ return; |
+ send_in_progress_ = false; |
+ if (rv < OK) |
+ connection_->OnError(this, rv); |
Sergey Ulanov
2014/09/19 21:11:27
Is OnConnectionError() handler allowed to delete M
Vitaly Buka (NO REVIEWS)
2014/09/19 21:33:27
Done.
|
+ while (!send_in_progress_ && !send_queue_.empty()) { |
+ scoped_refptr<IOBufferWithSize> buffer = send_queue_.front(); |
+ send_queue_.pop(); |
+ Send(buffer); |
+ } |
} |
MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) : |
@@ -141,24 +167,19 @@ bool MDnsConnection::Init(MDnsSocketFactory* socket_factory) { |
return !socket_handlers_.empty(); |
} |
-bool MDnsConnection::Send(IOBuffer* buffer, unsigned size) { |
- bool success = false; |
- for (size_t i = 0; i < socket_handlers_.size(); ++i) { |
- int rv = socket_handlers_[i]->Send(buffer, size); |
- if (rv >= OK || rv == ERR_IO_PENDING) { |
- success = true; |
- } else { |
- VLOG(1) << "Send failed, socket=" << i << ", error=" << rv; |
- } |
- } |
- return success; |
+void MDnsConnection::Send(const scoped_refptr<IOBufferWithSize>& buffer) { |
+ for (size_t i = 0; i < socket_handlers_.size(); ++i) |
+ socket_handlers_[i]->Send(buffer); |
} |
-void MDnsConnection::OnError(SocketHandler* loop, |
- int error) { |
+void MDnsConnection::OnError(SocketHandler* loop, int rv) { |
+ int socket = |
+ std::find(socket_handlers_.begin(), socket_handlers_.end(), loop) - |
+ socket_handlers_.begin(); |
+ VLOG(1) << "Socket error. id=" << socket << ", error=" << rv; |
// TODO(noamsml): Specific handling of intermittent errors that can be handled |
// in the connection. |
- delegate_->OnConnectionError(error); |
+ delegate_->OnConnectionError(rv); |
} |
void MDnsConnection::OnDatagramReceived( |
@@ -190,7 +211,8 @@ bool MDnsClientImpl::Core::SendQuery(uint16 rrtype, std::string name) { |
DnsQuery query(0, name_dns, rrtype); |
query.set_flags(0); // Remove the RD flag from the query. It is unneeded. |
- return connection_->Send(query.io_buffer(), query.io_buffer()->size()); |
+ connection_->Send(query.io_buffer()); |
+ return true; |
} |
void MDnsClientImpl::Core::HandlePacket(DnsResponse* response, |