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

Unified Diff: mojo/edk/system/raw_channel.cc

Issue 1403033003: Last set of fixes to make the src/mojo/edk pass the page cycler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: another small fix Created 5 years, 2 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
Index: mojo/edk/system/raw_channel.cc
diff --git a/mojo/edk/system/raw_channel.cc b/mojo/edk/system/raw_channel.cc
index 819762b301641ba7dba8030d134da1ae2abbaa38..554c1fdabf7dac4f0da442b12c71a13639db2cc7 100644
--- a/mojo/edk/system/raw_channel.cc
+++ b/mojo/edk/system/raw_channel.cc
@@ -170,6 +170,7 @@ RawChannel::RawChannel()
write_ready_(false),
write_stopped_(false),
error_occurred_(false),
+ pending_error_(false),
weak_ptr_factory_(this) {
read_buffer_.reset(new ReadBuffer);
write_buffer_.reset(new WriteBuffer());
@@ -330,11 +331,12 @@ bool RawChannel::SendQueuedMessagesNoLock() {
if (io_result == IO_PENDING)
return true;
- bool result = OnWriteCompletedNoLock(io_result, platform_handles_written,
- bytes_written);
+ bool result = OnWriteCompletedInternalNoLock(
+ io_result, platform_handles_written, bytes_written);
if (!result) {
// Even if we're on the I/O thread, don't call |OnError()| in the nested
// context.
+ pending_error_ = true;
yzshen1 2015/10/14 18:23:45 pending_error_ is never reset to false, is that in
jam 2015/10/14 20:01:44 yep
message_loop_for_io_->PostTask(
FROM_HERE,
base::Bind(&RawChannel::LockAndCallOnError,
@@ -377,10 +379,13 @@ void RawChannel::SetSerializedData(
}
void RawChannel::OnReadCompleted(IOResult io_result, size_t bytes_read) {
- DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
-
base::AutoLock locker(read_lock_);
+ OnReadCompletedNoLock(io_result, bytes_read);
+}
+void RawChannel::OnReadCompletedNoLock(IOResult io_result, size_t bytes_read) {
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
+ read_lock_.AssertAcquired();
// Keep reading data in a loop, and dispatch messages if enough data is
// received. Exit the loop if any of the following happens:
// - one or more messages were dispatched;
@@ -440,20 +445,21 @@ void RawChannel::OnReadCompleted(IOResult io_result, size_t bytes_read) {
void RawChannel::OnWriteCompleted(IOResult io_result,
size_t platform_handles_written,
size_t bytes_written) {
+ base::AutoLock locker(write_lock_);
+ OnWriteCompletedNoLock(io_result, platform_handles_written, bytes_written);
+}
+
+void RawChannel::OnWriteCompletedNoLock(IOResult io_result,
+ size_t platform_handles_written,
+ size_t bytes_written) {
DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
+ write_lock_.AssertAcquired();
DCHECK_NE(io_result, IO_PENDING);
- bool did_fail = false;
- {
- base::AutoLock locker(write_lock_);
- did_fail = !OnWriteCompletedNoLock(io_result, platform_handles_written,
- bytes_written);
- }
-
- if (did_fail) {
+ bool did_fail = !OnWriteCompletedInternalNoLock(
+ io_result, platform_handles_written, bytes_written);
+ if (did_fail)
LockAndCallOnError(Delegate::ERROR_WRITE);
- return; // |this| may have been destroyed in |CallOnError()|.
- }
}
void RawChannel::SerializeReadBuffer(size_t additional_bytes_read,
@@ -465,9 +471,9 @@ void RawChannel::SerializeReadBuffer(size_t additional_bytes_read,
}
void RawChannel::SerializeWriteBuffer(
- std::vector<char>* buffer,
size_t additional_bytes_written,
- size_t additional_platform_handles_written) {
+ size_t additional_platform_handles_written,
+ std::vector<char>* buffer) {
if (write_buffer_->IsEmpty()) {
DCHECK_EQ(0u, additional_bytes_written);
DCHECK_EQ(0u, additional_platform_handles_written);
@@ -497,6 +503,7 @@ void RawChannel::EnqueueMessageNoLock(scoped_ptr<MessageInTransit> message) {
bool RawChannel::OnReadMessageForRawChannel(
const MessageInTransit::View& message_view) {
if (message_view.type() == MessageInTransit::Type::RAW_CHANNEL_QUIT) {
+ pending_error_ = true;
message_loop_for_io_->PostTask(
FROM_HERE, base::Bind(&RawChannel::LockAndCallOnError,
weak_ptr_factory_.GetWeakPtr(),
@@ -530,9 +537,14 @@ RawChannel::Delegate::Error RawChannel::ReadIOResultToError(
void RawChannel::CallOnError(Delegate::Error error) {
DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
read_lock_.AssertAcquired();
+ bool called_on_error_before = error_occurred_;
error_occurred_ = true;
if (delegate_) {
- delegate_->OnError(error);
+ // We only want to call OnError once. The delegate may have posted a task
+ // to call Shutdown though, so we don't want to null delegate_ the first
+ // time and have two shutdown calls.
+ if (!called_on_error_before)
+ delegate_->OnError(error);
} else {
// We depend on delegate to delete since it could be waiting to call
// ReleaseHandle.
@@ -547,9 +559,9 @@ void RawChannel::LockAndCallOnError(Delegate::Error error) {
CallOnError(error);
}
-bool RawChannel::OnWriteCompletedNoLock(IOResult io_result,
- size_t platform_handles_written,
- size_t bytes_written) {
+bool RawChannel::OnWriteCompletedInternalNoLock(IOResult io_result,
+ size_t platform_handles_written,
+ size_t bytes_written) {
write_lock_.AssertAcquired();
DCHECK(!write_buffer_->message_queue_.IsEmpty());

Powered by Google App Engine
This is Rietveld 408576698