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

Unified Diff: mojo/message_pump/message_pump_mojo.cc

Issue 1841863002: Update monet. (Closed) Base URL: https://github.com/domokit/monet.git@master
Patch Set: Created 4 years, 9 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 | « mojo/message_pump/message_pump_mojo.h ('k') | mojo/message_pump/message_pump_mojo_handler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/message_pump/message_pump_mojo.cc
diff --git a/mojo/common/message_pump_mojo.cc b/mojo/message_pump/message_pump_mojo.cc
similarity index 68%
rename from mojo/common/message_pump_mojo.cc
rename to mojo/message_pump/message_pump_mojo.cc
index afbf8f983b8fb4b57de6d2982a0a59bd7d600840..471a0ad8332741702f947edc443e12cf78a0e3f0 100644
--- a/mojo/common/message_pump_mojo.cc
+++ b/mojo/message_pump/message_pump_mojo.cc
@@ -2,25 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "mojo/common/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo.h"
#include <algorithm>
#include <vector>
#include "base/debug/alias.h"
-#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/threading/thread_local.h"
#include "base/time/time.h"
-#include "mojo/common/message_pump_mojo_handler.h"
-#include "mojo/common/time_helper.h"
+#include "mojo/message_pump/message_pump_mojo_handler.h"
+#include "mojo/message_pump/time_helper.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+#include "mojo/public/cpp/system/wait.h"
namespace mojo {
namespace common {
namespace {
-base::LazyInstance<base::ThreadLocalPointer<MessagePumpMojo> >::Leaky
- g_tls_current_pump = LAZY_INSTANCE_INITIALIZER;
+base::ThreadLocalPointer<MessagePumpMojo>* CurrentPump() {
+ static auto* tls = new base::ThreadLocalPointer<MessagePumpMojo>;
+ return tls;
+}
MojoDeadline TimeTicksToMojoDeadline(base::TimeTicks time_ticks,
base::TimeTicks now) {
@@ -44,7 +47,7 @@ struct MessagePumpMojo::WaitState {
struct MessagePumpMojo::RunState {
RunState() : should_quit(false) {
- CreateMessagePipe(NULL, &read_handle, &write_handle);
+ CreateMessagePipe(nullptr, &read_handle, &write_handle);
}
base::TimeTicks delayed_work_time;
@@ -53,18 +56,22 @@ struct MessagePumpMojo::RunState {
ScopedMessagePipeHandle read_handle;
ScopedMessagePipeHandle write_handle;
+ // Cached structures to avoid the heap allocation cost of std::vector<>.
+ scoped_ptr<WaitState> wait_state;
+ scoped_ptr<HandleToHandlerList> cloned_handlers;
+
bool should_quit;
};
-MessagePumpMojo::MessagePumpMojo() : run_state_(NULL), next_handler_id_(0) {
+MessagePumpMojo::MessagePumpMojo() : run_state_(nullptr), next_handler_id_(0) {
DCHECK(!current())
<< "There is already a MessagePumpMojo instance on this thread.";
- g_tls_current_pump.Pointer()->Set(this);
+ CurrentPump()->Set(this);
}
MessagePumpMojo::~MessagePumpMojo() {
DCHECK_EQ(this, current());
- g_tls_current_pump.Pointer()->Set(NULL);
+ CurrentPump()->Set(nullptr);
}
// static
@@ -74,7 +81,7 @@ scoped_ptr<base::MessagePump> MessagePumpMojo::Create() {
// static
MessagePumpMojo* MessagePumpMojo::current() {
- return g_tls_current_pump.Pointer()->Get();
+ return CurrentPump()->Get();
}
void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler,
@@ -110,7 +117,7 @@ void MessagePumpMojo::Run(Delegate* delegate) {
// TODO: better deal with error handling.
CHECK(run_state.read_handle.is_valid());
CHECK(run_state.write_handle.is_valid());
- RunState* old_state = NULL;
+ RunState* old_state = nullptr;
{
base::AutoLock auto_lock(run_state_lock_);
old_state = run_state_;
@@ -172,47 +179,75 @@ void MessagePumpMojo::DoRunLoop(RunState* run_state, Delegate* delegate) {
bool MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) {
const MojoDeadline deadline = block ? GetDeadlineForWait(run_state) : 0;
- const WaitState wait_state = GetWaitState(run_state);
+ if (!run_state_->wait_state)
+ run_state_->wait_state.reset(new WaitState);
+ GetWaitState(run_state, run_state_->wait_state.get());
const WaitManyResult wait_many_result =
- WaitMany(wait_state.handles, wait_state.wait_signals, deadline, nullptr);
+ WaitMany(run_state_->wait_state->handles,
+ run_state_->wait_state->wait_signals, deadline, nullptr);
const MojoResult result = wait_many_result.result;
bool did_work = true;
if (result == MOJO_RESULT_OK) {
if (wait_many_result.index == 0) {
// Control pipe was written to.
- ReadMessageRaw(run_state.read_handle.get(), NULL, NULL, NULL, NULL,
- MOJO_READ_MESSAGE_FLAG_MAY_DISCARD);
+ ReadMessageRaw(run_state.read_handle.get(), nullptr, nullptr, nullptr,
+ nullptr, MOJO_READ_MESSAGE_FLAG_MAY_DISCARD);
} else {
- DCHECK(handlers_.find(wait_state.handles[wait_many_result.index]) !=
+ DCHECK(handlers_.find(
+ run_state_->wait_state->handles[wait_many_result.index]) !=
handlers_.end());
WillSignalHandler();
- handlers_[wait_state.handles[wait_many_result.index]]
- .handler->OnHandleReady(wait_state.handles[wait_many_result.index]);
+ handlers_[run_state_->wait_state->handles[wait_many_result.index]]
+ .handler->OnHandleReady(
+ run_state_->wait_state->handles[wait_many_result.index]);
DidSignalHandler();
}
} else {
switch (result) {
- case MOJO_RESULT_CANCELLED:
case MOJO_RESULT_FAILED_PRECONDITION:
- RemoveInvalidHandle(wait_state, result, wait_many_result.index);
+ RemoveInvalidHandle(*run_state_->wait_state, result,
+ wait_many_result.index);
break;
case MOJO_RESULT_DEADLINE_EXCEEDED:
did_work = false;
break;
+ case MOJO_RESULT_INVALID_ARGUMENT:
+ case MOJO_RESULT_CANCELLED:
+ case MOJO_RESULT_BUSY:
+ // These results indicate a bug in "our" code (e.g., race conditions).
+ // Fall through.
default:
base::debug::Alias(&result);
// Unexpected result is likely fatal, crash so we can determine cause.
CHECK(false);
}
}
+ // To keep memory usage under control, delete the WaitState object at the end
+ // if it's vectors are too big by a factor of 2. Pre-C++11 doesn't have a way
+ // to shrink vectors, so just get rid of them and re-create on the next round.
+ if (run_state_->wait_state->handles.capacity() >
+ 2 * run_state_->wait_state->handles.size()) {
+ // NOTE: |handles| and |wait_signals| are always in sync, so it's reasonable
+ // to only check one of those.
+ run_state_->wait_state.reset();
+ }
// Notify and remove any handlers whose time has expired. Make a copy in case
// someone tries to add/remove new handlers from notification.
- const HandleToHandler cloned_handlers(handlers_);
+ if (!run_state_->cloned_handlers) {
+ run_state_->cloned_handlers.reset(new HandleToHandlerList);
+ } else {
+ run_state_->cloned_handlers->clear();
+ }
+ run_state_->cloned_handlers->reserve(handlers_.size());
+ for (const auto& handler : handlers_) {
+ run_state_->cloned_handlers->push_back(handler);
+ }
const base::TimeTicks now(internal::NowTicks());
- for (HandleToHandler::const_iterator i = cloned_handlers.begin();
- i != cloned_handlers.end(); ++i) {
+ for (HandleToHandlerList::const_iterator i =
+ run_state_->cloned_handlers->begin();
+ i != run_state_->cloned_handlers->end(); ++i) {
// Since we're iterating over a clone of the handlers, verify the handler is
// still valid before notifying.
if (!i->second.deadline.is_null() && i->second.deadline < now &&
@@ -225,6 +260,10 @@ bool MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) {
did_work = true;
}
}
+ if (run_state_->cloned_handlers->capacity() >
+ 2 * run_state_->cloned_handlers->size()) {
+ run_state_->cloned_handlers.reset();
+ }
return did_work;
}
@@ -249,25 +288,29 @@ void MessagePumpMojo::RemoveInvalidHandle(const WaitState& wait_state,
void MessagePumpMojo::SignalControlPipe(const RunState& run_state) {
const MojoResult result =
- WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0,
+ WriteMessageRaw(run_state.write_handle.get(), nullptr, 0, nullptr, 0,
MOJO_WRITE_MESSAGE_FLAG_NONE);
// If we can't write we likely won't wake up the thread and there is a strong
// chance we'll deadlock.
CHECK_EQ(MOJO_RESULT_OK, result);
}
-MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState(
- const RunState& run_state) const {
- WaitState wait_state;
- wait_state.handles.push_back(run_state.read_handle.get());
- wait_state.wait_signals.push_back(MOJO_HANDLE_SIGNAL_READABLE);
+void MessagePumpMojo::GetWaitState(
+ const RunState& run_state,
+ MessagePumpMojo::WaitState* wait_state) const {
+ const size_t num_handles = handlers_.size() + 1;
+ wait_state->handles.clear();
+ wait_state->handles.reserve(num_handles);
+ wait_state->wait_signals.clear();
+ wait_state->wait_signals.reserve(num_handles);
+ wait_state->handles.push_back(run_state.read_handle.get());
+ wait_state->wait_signals.push_back(MOJO_HANDLE_SIGNAL_READABLE);
for (HandleToHandler::const_iterator i = handlers_.begin();
i != handlers_.end(); ++i) {
- wait_state.handles.push_back(i->first);
- wait_state.wait_signals.push_back(i->second.wait_signals);
+ wait_state->handles.push_back(i->first);
+ wait_state->wait_signals.push_back(i->second.wait_signals);
}
- return wait_state;
}
MojoDeadline MessagePumpMojo::GetDeadlineForWait(
« no previous file with comments | « mojo/message_pump/message_pump_mojo.h ('k') | mojo/message_pump/message_pump_mojo_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698