Index: content/browser/devtools/tethering_handler.cc |
diff --git a/content/browser/devtools/tethering_handler.cc b/content/browser/devtools/tethering_handler.cc |
index e0c083dd8ea8addee7a7491c8b9bbd9547af3bcd..5f039117ff4206c1913d195d1442604fc36cfa2d 100644 |
--- a/content/browser/devtools/tethering_handler.cc |
+++ b/content/browser/devtools/tethering_handler.cc |
@@ -16,7 +16,7 @@ |
#include "net/base/ip_endpoint.h" |
#include "net/base/net_errors.h" |
#include "net/base/net_log.h" |
-#include "net/socket/stream_listen_socket.h" |
+#include "net/socket/server_socket.h" |
#include "net/socket/stream_socket.h" |
#include "net/socket/tcp_server_socket.h" |
@@ -32,131 +32,130 @@ const int kBufferSize = 16 * 1024; |
const int kMinTetheringPort = 1024; |
const int kMaxTetheringPort = 32767; |
-class SocketPump : public net::StreamListenSocket::Delegate { |
+class SocketPump { |
public: |
SocketPump(DevToolsHttpHandlerDelegate* delegate, |
net::StreamSocket* client_socket) |
: client_socket_(client_socket), |
delegate_(delegate), |
- wire_buffer_size_(0), |
+ pending_writes_(0), |
pending_destruction_(false) { |
} |
std::string Init() { |
std::string channel_name; |
- server_socket_ = delegate_->CreateSocketForTethering(this, &channel_name); |
+ server_socket_ = delegate_->CreateSocketForTethering(&channel_name); |
if (!server_socket_.get() || channel_name.empty()) |
SelfDestruct(); |
+ |
+ int result = server_socket_->Accept( |
+ &accepted_socket_, |
+ base::Bind(&SocketPump::OnAccepted, base::Unretained(this))); |
+ if (result != net::ERR_IO_PENDING) |
+ OnAccepted(result); |
return channel_name; |
} |
- ~SocketPump() override {} |
- |
private: |
- void DidAccept(net::StreamListenSocket* server, |
- scoped_ptr<net::StreamListenSocket> socket) override { |
- if (accepted_socket_.get()) |
+ void OnAccepted(int result) { |
+ if (result < 0) { |
+ SelfDestruct(); |
return; |
+ } |
- buffer_ = new net::IOBuffer(kBufferSize); |
- wire_buffer_ = new net::GrowableIOBuffer(); |
- wire_buffer_->SetCapacity(kBufferSize); |
+ ++pending_writes_; // avoid SelfDestruct in first Pump |
+ Pump(client_socket_.get(), accepted_socket_.get()); |
+ --pending_writes_; |
+ if (pending_destruction_) { |
+ SelfDestruct(); |
+ } else { |
+ Pump(accepted_socket_.get(), client_socket_.get()); |
+ } |
+ } |
- accepted_socket_ = socket.Pass(); |
- int result = client_socket_->Read( |
- buffer_.get(), |
+ void Pump(net::StreamSocket* from, net::StreamSocket* to) { |
+ scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize); |
+ int result = from->Read( |
+ buffer.get(), |
kBufferSize, |
- base::Bind(&SocketPump::OnClientRead, base::Unretained(this))); |
+ base::Bind( |
+ &SocketPump::OnRead, base::Unretained(this), from, to, buffer)); |
if (result != net::ERR_IO_PENDING) |
- OnClientRead(result); |
- } |
- |
- void DidRead(net::StreamListenSocket* socket, |
- const char* data, |
- int len) override { |
- int old_size = wire_buffer_size_; |
- wire_buffer_size_ += len; |
- while (wire_buffer_->capacity() < wire_buffer_size_) |
- wire_buffer_->SetCapacity(wire_buffer_->capacity() * 2); |
- memcpy(wire_buffer_->StartOfBuffer() + old_size, data, len); |
- if (old_size != wire_buffer_->offset()) |
- return; |
- OnClientWrite(0); |
+ OnRead(from, to, buffer, result); |
} |
- void DidClose(net::StreamListenSocket* socket) override { SelfDestruct(); } |
- |
- void OnClientRead(int result) { |
+ void OnRead(net::StreamSocket* from, |
+ net::StreamSocket* to, |
+ scoped_refptr<net::IOBuffer> buffer, |
+ int result) { |
if (result <= 0) { |
SelfDestruct(); |
return; |
} |
- accepted_socket_->Send(buffer_->data(), result); |
- result = client_socket_->Read( |
- buffer_.get(), |
- kBufferSize, |
- base::Bind(&SocketPump::OnClientRead, base::Unretained(this))); |
+ int total = result; |
+ scoped_refptr<net::DrainableIOBuffer> drainable = |
+ new net::DrainableIOBuffer(buffer.get(), total); |
+ |
+ ++pending_writes_; |
+ result = to->Write(drainable.get(), |
+ total, |
+ base::Bind(&SocketPump::OnWritten, |
+ base::Unretained(this), |
+ drainable, |
+ from, |
+ to)); |
if (result != net::ERR_IO_PENDING) |
- OnClientRead(result); |
+ OnWritten(drainable, from, to, result); |
} |
- void OnClientWrite(int result) { |
+ void OnWritten(scoped_refptr<net::DrainableIOBuffer> drainable, |
+ net::StreamSocket* from, |
+ net::StreamSocket* to, |
+ int result) { |
+ --pending_writes_; |
if (result < 0) { |
SelfDestruct(); |
return; |
} |
- wire_buffer_->set_offset(wire_buffer_->offset() + result); |
- |
- int remaining = wire_buffer_size_ - wire_buffer_->offset(); |
- if (remaining == 0) { |
- if (pending_destruction_) |
- SelfDestruct(); |
+ drainable->DidConsume(result); |
+ if (drainable->BytesRemaining() > 0) { |
+ ++pending_writes_; |
+ result = to->Write(drainable.get(), |
+ drainable->BytesRemaining(), |
+ base::Bind(&SocketPump::OnWritten, |
+ base::Unretained(this), |
+ drainable, |
+ from, |
+ to)); |
+ if (result != net::ERR_IO_PENDING) |
+ OnWritten(drainable, from, to, result); |
return; |
} |
- |
- if (remaining > kBufferSize) |
- remaining = kBufferSize; |
- |
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(remaining); |
- memcpy(buffer->data(), wire_buffer_->data(), remaining); |
- result = client_socket_->Write( |
- buffer.get(), |
- remaining, |
- base::Bind(&SocketPump::OnClientWrite, base::Unretained(this))); |
- |
- // Shrink buffer |
- int offset = wire_buffer_->offset(); |
- if (offset > kBufferSize) { |
- memcpy(wire_buffer_->StartOfBuffer(), wire_buffer_->data(), |
- wire_buffer_size_ - offset); |
- wire_buffer_size_ -= offset; |
- wire_buffer_->set_offset(0); |
+ if (pending_destruction_) { |
+ SelfDestruct(); |
+ return; |
} |
- |
- if (result != net::ERR_IO_PENDING) |
- OnClientWrite(result); |
- return; |
+ Pump(from, to); |
} |
void SelfDestruct() { |
- if (wire_buffer_.get() && wire_buffer_->offset() != wire_buffer_size_) { |
+ if (pending_writes_ > 0) { |
pending_destruction_ = true; |
return; |
} |
delete this; |
} |
+ |
private: |
scoped_ptr<net::StreamSocket> client_socket_; |
- scoped_ptr<net::StreamListenSocket> server_socket_; |
- scoped_ptr<net::StreamListenSocket> accepted_socket_; |
- scoped_refptr<net::IOBuffer> buffer_; |
- scoped_refptr<net::GrowableIOBuffer> wire_buffer_; |
+ scoped_ptr<net::ServerSocket> server_socket_; |
+ scoped_ptr<net::StreamSocket> accepted_socket_; |
DevToolsHttpHandlerDelegate* delegate_; |
- int wire_buffer_size_; |
+ int pending_writes_; |
bool pending_destruction_; |
}; |