Oops, calling {Producer,Consumer}CloseImplNoLock() isn't the same as calling {Producer,Consumer}Close().
In particular, we need to wake up any waiters when we go away. (We'll
need this when serializing for real also.)
R=yzshen@chromium.org
Review URL: https://codereview.chromium.org/936283002
diff --git a/mojo/edk/system/data_pipe.cc b/mojo/edk/system/data_pipe.cc
index 3b71d6d..aede492 100644
--- a/mojo/edk/system/data_pipe.cc
+++ b/mojo/edk/system/data_pipe.cc
@@ -91,17 +91,7 @@
void DataPipe::ProducerClose() {
base::AutoLock locker(lock_);
- DCHECK(producer_open_);
- producer_open_ = false;
- DCHECK(has_local_producer_no_lock());
- producer_awakable_list_.reset();
- // Not a bug, except possibly in "user" code.
- DVLOG_IF(2, producer_in_two_phase_write_no_lock())
- << "Producer closed with active two-phase write";
- producer_two_phase_max_num_bytes_written_ = 0;
- ProducerCloseImplNoLock();
- AwakeConsumerAwakablesForStateChangeNoLock(
- ConsumerGetHandleSignalsStateImplNoLock());
+ ProducerCloseNoLock();
}
MojoResult DataPipe::ProducerWriteData(UserPointer<const void> elements,
@@ -271,17 +261,7 @@
void DataPipe::ConsumerClose() {
base::AutoLock locker(lock_);
- DCHECK(consumer_open_);
- consumer_open_ = false;
- DCHECK(has_local_consumer_no_lock());
- consumer_awakable_list_.reset();
- // Not a bug, except possibly in "user" code.
- DVLOG_IF(2, consumer_in_two_phase_read_no_lock())
- << "Consumer closed with active two-phase read";
- consumer_two_phase_max_num_bytes_read_ = 0;
- ConsumerCloseImplNoLock();
- AwakeProducerAwakablesForStateChangeNoLock(
- ProducerGetHandleSignalsStateImplNoLock());
+ ConsumerCloseNoLock();
}
MojoResult DataPipe::ConsumerReadData(UserPointer<void> elements,
@@ -501,6 +481,36 @@
DCHECK(!consumer_awakable_list_);
}
+void DataPipe::ProducerCloseNoLock() {
+ lock_.AssertAcquired();
+ DCHECK(producer_open_);
+ producer_open_ = false;
+ DCHECK(has_local_producer_no_lock());
+ producer_awakable_list_.reset();
+ // Not a bug, except possibly in "user" code.
+ DVLOG_IF(2, producer_in_two_phase_write_no_lock())
+ << "Producer closed with active two-phase write";
+ producer_two_phase_max_num_bytes_written_ = 0;
+ ProducerCloseImplNoLock();
+ AwakeConsumerAwakablesForStateChangeNoLock(
+ ConsumerGetHandleSignalsStateImplNoLock());
+}
+
+void DataPipe::ConsumerCloseNoLock() {
+ lock_.AssertAcquired();
+ DCHECK(consumer_open_);
+ consumer_open_ = false;
+ DCHECK(has_local_consumer_no_lock());
+ consumer_awakable_list_.reset();
+ // Not a bug, except possibly in "user" code.
+ DVLOG_IF(2, consumer_in_two_phase_read_no_lock())
+ << "Consumer closed with active two-phase read";
+ consumer_two_phase_max_num_bytes_read_ = 0;
+ ConsumerCloseImplNoLock();
+ AwakeProducerAwakablesForStateChangeNoLock(
+ ProducerGetHandleSignalsStateImplNoLock());
+}
+
void DataPipe::AwakeProducerAwakablesForStateChangeNoLock(
const HandleSignalsState& new_producer_state) {
lock_.AssertAcquired();
diff --git a/mojo/edk/system/data_pipe.h b/mojo/edk/system/data_pipe.h
index 39954d4..585893e 100644
--- a/mojo/edk/system/data_pipe.h
+++ b/mojo/edk/system/data_pipe.h
@@ -116,6 +116,9 @@
friend class base::RefCountedThreadSafe<DataPipe>;
virtual ~DataPipe();
+ void ProducerCloseNoLock();
+ void ConsumerCloseNoLock();
+
virtual void ProducerCloseImplNoLock() = 0;
// |num_bytes.Get()| will be a nonzero multiple of |element_num_bytes_|.
virtual MojoResult ProducerWriteDataImplNoLock(
diff --git a/mojo/edk/system/local_data_pipe.cc b/mojo/edk/system/local_data_pipe.cc
index c0ee16b..6d0760b 100644
--- a/mojo/edk/system/local_data_pipe.cc
+++ b/mojo/edk/system/local_data_pipe.cc
@@ -182,7 +182,7 @@
size_t* actual_size,
embedder::PlatformHandleVector* platform_handles) {
// TODO(vtl): Support serializing producer data pipe handles.
- ProducerCloseImplNoLock();
+ ProducerCloseNoLock();
return false;
}
@@ -336,7 +336,7 @@
size_t* actual_size,
embedder::PlatformHandleVector* platform_handles) {
// TODO(vtl): Support serializing consumer data pipe handles.
- ConsumerCloseImplNoLock();
+ ConsumerCloseNoLock();
return false;
}