Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(982)

Unified Diff: remoting/protocol/buffered_socket_writer.cc

Issue 10836030: Add unittests for BufferedSocketWriter and fix some bugs in that code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « remoting/protocol/buffered_socket_writer.h ('k') | remoting/protocol/buffered_socket_writer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/protocol/buffered_socket_writer.cc
diff --git a/remoting/protocol/buffered_socket_writer.cc b/remoting/protocol/buffered_socket_writer.cc
index f0ab9f22d1c82ded0872e614f9ba38d36ed04c7b..178f14a9e2091b2f79daa4979735959ce3cf5a88 100644
--- a/remoting/protocol/buffered_socket_writer.cc
+++ b/remoting/protocol/buffered_socket_writer.cc
@@ -6,40 +6,31 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
+#include "base/thread_task_runner_handle.h"
#include "net/base/net_errors.h"
namespace remoting {
namespace protocol {
-class BufferedSocketWriterBase::PendingPacket {
- public:
+struct BufferedSocketWriterBase::PendingPacket {
PendingPacket(scoped_refptr<net::IOBufferWithSize> data,
const base::Closure& done_task)
- : data_(data),
- done_task_(done_task) {
+ : data(data),
+ done_task(done_task) {
}
- ~PendingPacket() {
- if (!done_task_.is_null())
- done_task_.Run();
- }
-
- net::IOBufferWithSize* data() {
- return data_;
- }
-
- private:
- scoped_refptr<net::IOBufferWithSize> data_;
- base::Closure done_task_;
- DISALLOW_COPY_AND_ASSIGN(PendingPacket);
+ scoped_refptr<net::IOBufferWithSize> data;
+ base::Closure done_task;
};
BufferedSocketWriterBase::BufferedSocketWriterBase()
: buffer_size_(0),
socket_(NULL),
write_pending_(false),
- closed_(false) {
+ closed_(false),
+ destroyed_flag_(NULL) {
}
void BufferedSocketWriterBase::Init(net::Socket* socket,
@@ -54,6 +45,7 @@ bool BufferedSocketWriterBase::Write(
scoped_refptr<net::IOBufferWithSize> data, const base::Closure& done_task) {
DCHECK(CalledOnValidThread());
DCHECK(socket_);
+ DCHECK(data.get());
// Don't write after Close().
if (closed_)
@@ -91,35 +83,51 @@ void BufferedSocketWriterBase::DoWrite() {
current_packet, current_packet_size,
base::Bind(&BufferedSocketWriterBase::OnWritten,
base::Unretained(this)));
- if (result >= 0) {
- AdvanceBufferPosition(result);
+ bool write_again = false;
+ HandleWriteResult(result, &write_again);
+ if (!write_again)
+ return;
+ }
+}
+
+void BufferedSocketWriterBase::HandleWriteResult(int result,
+ bool* write_again) {
+ *write_again = false;
+ if (result < 0) {
+ if (result == net::ERR_IO_PENDING) {
+ write_pending_ = true;
} else {
- if (result == net::ERR_IO_PENDING) {
- write_pending_ = true;
- } else {
- HandleError(result);
- if (!write_failed_callback_.is_null())
- write_failed_callback_.Run(result);
- }
+ HandleError(result);
+ if (!write_failed_callback_.is_null())
+ write_failed_callback_.Run(result);
+ }
+ return;
+ }
+
+ base::Closure done_task = AdvanceBufferPosition(result);
+ if (!done_task.is_null()) {
+ bool destroyed = false;
+ destroyed_flag_ = &destroyed;
+ done_task.Run();
+ if (destroyed) {
+ // Stop doing anything if we've been destroyed by the callback.
return;
}
+ destroyed_flag_ = NULL;
}
+
+ *write_again = true;
}
void BufferedSocketWriterBase::OnWritten(int result) {
DCHECK(CalledOnValidThread());
+ DCHECK(write_pending_);
write_pending_ = false;
- if (result < 0) {
- HandleError(result);
- if (!write_failed_callback_.is_null())
- write_failed_callback_.Run(result);
- return;
- }
-
- AdvanceBufferPosition(result);
-
- DoWrite();
+ bool write_again;
+ HandleWriteResult(result, &write_again);
+ if (write_again)
+ DoWrite();
}
void BufferedSocketWriterBase::HandleError(int result) {
@@ -146,12 +154,18 @@ void BufferedSocketWriterBase::Close() {
closed_ = true;
}
-BufferedSocketWriterBase::~BufferedSocketWriterBase() {}
+BufferedSocketWriterBase::~BufferedSocketWriterBase() {
+ if (destroyed_flag_)
+ *destroyed_flag_ = true;
+
+ STLDeleteElements(&queue_);
+}
-void BufferedSocketWriterBase::PopQueue() {
- // This also calls |done_task|.
+base::Closure BufferedSocketWriterBase::PopQueue() {
+ base::Closure result = queue_.front()->done_task;
delete queue_.front();
queue_.pop_front();
+ return result;
}
BufferedSocketWriter::BufferedSocketWriter() {
@@ -165,21 +179,22 @@ void BufferedSocketWriter::GetNextPacket(
return; // Nothing to write.
}
current_buf_ = new net::DrainableIOBuffer(
- queue_.front()->data(), queue_.front()->data()->size());
+ queue_.front()->data, queue_.front()->data->size());
}
*buffer = current_buf_;
*size = current_buf_->BytesRemaining();
}
-void BufferedSocketWriter::AdvanceBufferPosition(int written) {
+base::Closure BufferedSocketWriter::AdvanceBufferPosition(int written) {
buffer_size_ -= written;
current_buf_->DidConsume(written);
if (current_buf_->BytesRemaining() == 0) {
- PopQueue();
current_buf_ = NULL;
+ return PopQueue();
}
+ return base::Closure();
}
void BufferedSocketWriter::OnError(int result) {
@@ -187,7 +202,6 @@ void BufferedSocketWriter::OnError(int result) {
}
BufferedSocketWriter::~BufferedSocketWriter() {
- STLDeleteElements(&queue_);
}
BufferedDatagramWriter::BufferedDatagramWriter() {
@@ -199,21 +213,22 @@ void BufferedDatagramWriter::GetNextPacket(
*buffer = NULL;
return; // Nothing to write.
}
- *buffer = queue_.front()->data();
- *size = queue_.front()->data()->size();
+ *buffer = queue_.front()->data;
+ *size = queue_.front()->data->size();
}
-void BufferedDatagramWriter::AdvanceBufferPosition(int written) {
- DCHECK_EQ(written, queue_.front()->data()->size());
- buffer_size_ -= queue_.front()->data()->size();
- PopQueue();
+base::Closure BufferedDatagramWriter::AdvanceBufferPosition(int written) {
+ DCHECK_EQ(written, queue_.front()->data->size());
+ buffer_size_ -= queue_.front()->data->size();
+ return PopQueue();
}
void BufferedDatagramWriter::OnError(int result) {
// Nothing to do here.
}
-BufferedDatagramWriter::~BufferedDatagramWriter() {}
+BufferedDatagramWriter::~BufferedDatagramWriter() {
+}
} // namespace protocol
} // namespace remoting
« no previous file with comments | « remoting/protocol/buffered_socket_writer.h ('k') | remoting/protocol/buffered_socket_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698