Chromium Code Reviews| Index: net/quic/quic_server_packet_writer.cc |
| diff --git a/net/quic/quic_server_packet_writer.cc b/net/quic/quic_server_packet_writer.cc |
| index c2635b699eb3efd06713015d8ba6fcd1a2d93a4e..8ffc309915ded63466fc0281a03ce6c4e4e9ddf4 100644 |
| --- a/net/quic/quic_server_packet_writer.cc |
| +++ b/net/quic/quic_server_packet_writer.cc |
| @@ -4,50 +4,49 @@ |
| #include "net/quic/quic_server_packet_writer.h" |
| +#include "base/callback_helpers.h" |
| #include "base/location.h" |
| #include "base/logging.h" |
| #include "base/metrics/sparse_histogram.h" |
| #include "net/base/io_buffer.h" |
| #include "net/base/net_errors.h" |
| +#include "net/udp/udp_server_socket.h" |
| namespace net { |
| -QuicServerPacketWriter::QuicServerPacketWriter() : weak_factory_(this) { |
| -} |
| - |
| -QuicServerPacketWriter::QuicServerPacketWriter(UDPServerSocket* socket) |
| +QuicServerPacketWriter::QuicServerPacketWriter( |
| + UDPServerSocket* socket, |
| + QuicBlockedWriterInterface* blocked_writer) |
| : weak_factory_(this), |
| socket_(socket), |
| + blocked_writer_(blocked_writer), |
| write_blocked_(false) { |
| } |
| QuicServerPacketWriter::~QuicServerPacketWriter() { |
| } |
| -WriteResult QuicServerPacketWriter::WritePacket( |
| - const char* buffer, size_t buf_len, |
| - const net::IPAddressNumber& self_address, |
| - const net::IPEndPoint& peer_address) { |
| - scoped_refptr<StringIOBuffer> buf( |
| - new StringIOBuffer(std::string(buffer, buf_len))); |
| - DCHECK(!IsWriteBlocked()); |
| - int rv = socket_->SendTo(buf.get(), |
| - buf_len, |
| - peer_address, |
| - base::Bind(&QuicServerPacketWriter::OnWriteComplete, |
| - weak_factory_.GetWeakPtr())); |
| - WriteStatus status = WRITE_STATUS_OK; |
| - if (rv < 0) { |
| - if (rv != ERR_IO_PENDING) { |
| - UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.WriteError", -rv); |
| - status = WRITE_STATUS_ERROR; |
| - } else { |
| - status = WRITE_STATUS_BLOCKED; |
| - write_blocked_ = true; |
| - } |
| +WriteResult QuicServerPacketWriter::WritePacketWithCallback( |
| + const char* buffer, |
| + size_t buf_len, |
| + const IPAddressNumber& self_address, |
| + const IPEndPoint& peer_address, |
| + WriteCallback callback) { |
| + DCHECK(callback_.is_null()); |
| + callback_ = callback; |
| + WriteResult result = WritePacket(buffer, buf_len, self_address, peer_address); |
| + if (result.status != WRITE_STATUS_BLOCKED) { |
| + callback_.Reset(); |
| } |
| + return result; |
| +} |
| - return WriteResult(status, rv); |
| +void QuicServerPacketWriter::OnWriteComplete(int rv) { |
| + DCHECK_NE(rv, ERR_IO_PENDING); |
| + write_blocked_ = false; |
| + WriteResult result(rv < 0 ? WRITE_STATUS_ERROR : WRITE_STATUS_OK, rv); |
| + base::ResetAndReturn(&callback_).Run(result); |
| + blocked_writer_->OnCanWrite(); |
| } |
| bool QuicServerPacketWriter::IsWriteBlockedDataBuffered() const { |
| @@ -63,12 +62,36 @@ void QuicServerPacketWriter::SetWritable() { |
| write_blocked_ = false; |
| } |
| -void QuicServerPacketWriter::OnWriteComplete(int rv) { |
| - DCHECK_NE(rv, ERR_IO_PENDING); |
| - write_blocked_ = false; |
| - WriteResult result(rv < 0 ? WRITE_STATUS_ERROR : WRITE_STATUS_OK, rv); |
| - connection_->OnPacketSent(result); |
| - connection_->OnCanWrite(); |
| +WriteResult QuicServerPacketWriter::WritePacket( |
| + const char* buffer, |
| + size_t buf_len, |
| + const IPAddressNumber& self_address, |
| + const IPEndPoint& peer_address) { |
| + scoped_refptr<StringIOBuffer> buf( |
| + new StringIOBuffer(std::string(buffer, buf_len))); |
| + DCHECK(!IsWriteBlocked()); |
| + DCHECK(!callback_.is_null()); |
| + int rv; |
| + if (buf_len <= static_cast<size_t>(std::numeric_limits<int>::max())) { |
|
wtc
2014/06/24 21:47:21
I confirm this check is correct.
|
| + rv = socket_->SendTo(buf.get(), |
| + static_cast<int>(buf_len), |
| + peer_address, |
| + base::Bind(&QuicServerPacketWriter::OnWriteComplete, |
| + weak_factory_.GetWeakPtr())); |
| + } else { |
| + rv = ERR_MSG_TOO_BIG; |
| + } |
| + WriteStatus status = WRITE_STATUS_OK; |
| + if (rv < 0) { |
| + if (rv != ERR_IO_PENDING) { |
| + UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.WriteError", -rv); |
| + status = WRITE_STATUS_ERROR; |
| + } else { |
| + status = WRITE_STATUS_BLOCKED; |
| + write_blocked_ = true; |
| + } |
| + } |
| + return WriteResult(status, rv); |
| } |
| } // namespace net |