Index: jingle/glue/channel_socket_adapter.cc |
diff --git a/jingle/glue/channel_socket_adapter.cc b/jingle/glue/channel_socket_adapter.cc |
index 3e22a35194223f819209141f5f293f6198fae949..39b3eb45c86dff880f54d3ce59e4432068d30ee9 100644 |
--- a/jingle/glue/channel_socket_adapter.cc |
+++ b/jingle/glue/channel_socket_adapter.cc |
@@ -19,7 +19,7 @@ TransportChannelSocketAdapter::TransportChannelSocketAdapter( |
: message_loop_(MessageLoop::current()), |
channel_(channel), |
old_read_callback_(NULL), |
- write_callback_(NULL), |
+ old_write_callback_(NULL), |
closed_error_code_(net::OK) { |
DCHECK(channel_); |
@@ -73,11 +73,47 @@ int TransportChannelSocketAdapter::Read( |
} |
int TransportChannelSocketAdapter::Write( |
- net::IOBuffer* buffer, int buffer_size, net::OldCompletionCallback* callback) { |
+ net::IOBuffer* buffer, int buffer_size, |
+ net::OldCompletionCallback* callback) { |
DCHECK_EQ(MessageLoop::current(), message_loop_); |
DCHECK(buffer); |
DCHECK(callback); |
- CHECK(!write_callback_); |
+ CHECK(!old_write_callback_ && write_callback_.is_null()); |
+ |
+ if (!channel_) { |
+ DCHECK(closed_error_code_ != net::OK); |
+ return closed_error_code_; |
+ } |
+ |
+ int result; |
+ if (channel_->writable()) { |
+ result = channel_->SendPacket(buffer->data(), buffer_size); |
+ if (result < 0) { |
+ result = net::MapSystemError(channel_->GetError()); |
+ |
+ // If the underlying socket returns IO pending where it shouldn't we |
+ // pretend the packet is dropped and return as succeeded because no |
+ // writeable callback will happen. |
+ if (result == net::ERR_IO_PENDING) |
+ result = net::OK; |
+ } |
+ } else { |
+ // Channel is not writable yet. |
+ result = net::ERR_IO_PENDING; |
+ old_write_callback_ = callback; |
+ write_buffer_ = buffer; |
+ write_buffer_size_ = buffer_size; |
+ } |
+ |
+ return result; |
+} |
+int TransportChannelSocketAdapter::Write( |
+ net::IOBuffer* buffer, int buffer_size, |
+ const net::CompletionCallback& callback) { |
+ DCHECK_EQ(MessageLoop::current(), message_loop_); |
+ DCHECK(buffer); |
+ DCHECK(!callback.is_null()); |
+ CHECK(!old_write_callback_ && write_callback_.is_null()); |
if (!channel_) { |
DCHECK(closed_error_code_ != net::OK); |
@@ -141,11 +177,16 @@ void TransportChannelSocketAdapter::Close(int error_code) { |
callback.Run(error_code); |
} |
- if (write_callback_) { |
- net::OldCompletionCallback* callback = write_callback_; |
- write_callback_ = NULL; |
+ if (old_write_callback_) { |
+ net::OldCompletionCallback* callback = old_write_callback_; |
+ old_write_callback_ = NULL; |
write_buffer_ = NULL; |
callback->Run(error_code); |
+ } else if (!write_callback_.is_null()) { |
+ net::CompletionCallback callback = write_callback_; |
+ write_callback_.Reset(); |
+ write_buffer_ = NULL; |
+ callback.Run(error_code); |
} |
} |
@@ -186,17 +227,24 @@ void TransportChannelSocketAdapter::OnWritableState( |
cricket::TransportChannel* channel) { |
DCHECK_EQ(MessageLoop::current(), message_loop_); |
// Try to send the packet if there is a pending write. |
- if (write_callback_) { |
+ if (old_write_callback_ || !write_callback_.is_null()) { |
int result = channel_->SendPacket(write_buffer_->data(), |
write_buffer_size_); |
if (result < 0) |
result = net::MapSystemError(channel_->GetError()); |
if (result != net::ERR_IO_PENDING) { |
- net::OldCompletionCallback* callback = write_callback_; |
- write_callback_ = NULL; |
- write_buffer_ = NULL; |
- callback->Run(result); |
+ if (old_write_callback_) { |
+ net::OldCompletionCallback* callback = old_write_callback_; |
+ old_write_callback_ = NULL; |
+ write_buffer_ = NULL; |
+ callback->Run(result); |
+ } else { |
+ net::CompletionCallback callback = write_callback_; |
+ write_callback_.Reset(); |
+ write_buffer_ = NULL; |
+ callback.Run(result); |
+ } |
} |
} |
} |