| Index: mojo/system/core_impl.cc
|
| diff --git a/mojo/system/core_impl.cc b/mojo/system/core_impl.cc
|
| index 70a8e2b3ab72c6327d4c7045644f55daba6c23d5..6075149fa7c1253623b662c310b40af3b1a47cc9 100644
|
| --- a/mojo/system/core_impl.cc
|
| +++ b/mojo/system/core_impl.cc
|
| @@ -244,6 +244,11 @@ MojoResult CoreImpl::WriteMessage(
|
| break;
|
| }
|
|
|
| + // We shouldn't race with things that close dispatchers, since closing can
|
| + // only take place either under |handle_table_lock_| or when the handle is
|
| + // marked as busy.
|
| + DCHECK(!entries[i]->dispatcher->is_closed_no_lock());
|
| +
|
| // Hang on to the pointer to the dispatcher (which we'll need to release
|
| // the lock without going through the handle table).
|
| dispatchers[i] = entries[i]->dispatcher;
|
| @@ -281,6 +286,7 @@ MojoResult CoreImpl::WriteMessage(
|
| HandleTableMap::iterator it = handle_table_.find(handles[i]);
|
| DCHECK(it != handle_table_.end());
|
| DCHECK(it->second.busy);
|
| + it->second.busy = false; // For the sake of a |DCHECK()|.
|
| handle_table_.erase(it);
|
| }
|
| } else {
|
| @@ -307,28 +313,25 @@ MojoResult CoreImpl::ReadMessage(
|
| if (!dispatcher.get())
|
| return MOJO_RESULT_INVALID_ARGUMENT;
|
|
|
| - uint32_t max_num_dispatchers = 0;
|
| if (num_handles) {
|
| if (!VerifyUserPointer<uint32_t>(num_handles, 1))
|
| return MOJO_RESULT_INVALID_ARGUMENT;
|
| if (!VerifyUserPointer<MojoHandle>(handles, *num_handles))
|
| return MOJO_RESULT_INVALID_ARGUMENT;
|
| - max_num_dispatchers = *num_handles;
|
| }
|
|
|
| // Easy case: won't receive any handles.
|
| - if (max_num_dispatchers == 0)
|
| + if (!num_handles || *num_handles == 0)
|
| return dispatcher->ReadMessage(bytes, num_bytes, 0, NULL, flags);
|
|
|
| std::vector<scoped_refptr<Dispatcher> > dispatchers;
|
| MojoResult rv = dispatcher->ReadMessage(bytes, num_bytes,
|
| - max_num_dispatchers, &dispatchers,
|
| + &dispatchers, num_handles,
|
| flags);
|
| if (!dispatchers.empty()) {
|
| DCHECK_EQ(rv, MOJO_RESULT_OK);
|
| -
|
| - *num_handles = static_cast<uint32_t>(dispatchers.size());
|
| - DCHECK_LE(*num_handles, max_num_dispatchers);
|
| + DCHECK(num_handles);
|
| + DCHECK_LE(dispatchers.size(), static_cast<size_t>(*num_handles));
|
|
|
| base::AutoLock locker(handle_table_lock_);
|
|
|
|
|