Commit 95d70989 authored by sky@chromium.org's avatar sky@chromium.org

Adds some CHECKs to MessagePumpMojo

The thread watcher appears to be kicking on when we're trying to
remove a handle. Not sure why. This converts some DCHECKs to CHECKs
and fixes handling of the deadline. I suspect none of this will help,
but it's worth a shot.

BUG=399769
TEST=none
R=darin@chromium.org

Review URL: https://codereview.chromium.org/454433003

Cr-Commit-Position: refs/heads/master@{#288949}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288949 0039d316-1c4b-4281-b951-d872f2087c98
parent 4bfc5827
...@@ -92,6 +92,8 @@ MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL; ...@@ -92,6 +92,8 @@ MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL;
// time for every task that is added to the MessageLoop incoming queue. // time for every task that is added to the MessageLoop incoming queue.
bool AlwaysNotifyPump(MessageLoop::Type type) { bool AlwaysNotifyPump(MessageLoop::Type type) {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// The Android UI message loop needs to get notified each time a task is added
// to the incoming queue.
return type == MessageLoop::TYPE_UI || type == MessageLoop::TYPE_JAVA; return type == MessageLoop::TYPE_UI || type == MessageLoop::TYPE_JAVA;
#else #else
return false; return false;
...@@ -528,8 +530,6 @@ void MessageLoop::ReloadWorkQueue() { ...@@ -528,8 +530,6 @@ void MessageLoop::ReloadWorkQueue() {
} }
void MessageLoop::ScheduleWork(bool was_empty) { void MessageLoop::ScheduleWork(bool was_empty) {
// The Android UI message loop needs to get notified each time
// a task is added to the incoming queue.
if (was_empty || AlwaysNotifyPump(type_)) if (was_empty || AlwaysNotifyPump(type_))
pump_->ScheduleWork(); pump_->ScheduleWork();
} }
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "base/files/scoped_file.h" #include "base/files/scoped_file.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
#include "mojo/common/handle_watcher.h"
namespace mojo { namespace mojo {
namespace common { namespace common {
......
...@@ -15,6 +15,19 @@ ...@@ -15,6 +15,19 @@
namespace mojo { namespace mojo {
namespace common { namespace common {
namespace {
MojoDeadline TimeTicksToMojoDeadline(base::TimeTicks time_ticks,
base::TimeTicks now) {
// The is_null() check matches that of HandleWatcher.
if (time_ticks.is_null())
return MOJO_DEADLINE_INDEFINITE;
const int64_t delta = (time_ticks - now).InMicroseconds();
return delta < 0 ? static_cast<MojoDeadline>(0) :
static_cast<MojoDeadline>(delta);
}
} // namespace
// State needed for one iteration of WaitMany. The first handle and flags // State needed for one iteration of WaitMany. The first handle and flags
// corresponds to that of the control pipe. // corresponds to that of the control pipe.
...@@ -52,10 +65,10 @@ void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler, ...@@ -52,10 +65,10 @@ void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler,
const Handle& handle, const Handle& handle,
MojoHandleSignals wait_signals, MojoHandleSignals wait_signals,
base::TimeTicks deadline) { base::TimeTicks deadline) {
DCHECK(handler); CHECK(handler);
DCHECK(handle.is_valid()); DCHECK(handle.is_valid());
// Assume it's an error if someone tries to reregister an existing handle. // Assume it's an error if someone tries to reregister an existing handle.
DCHECK_EQ(0u, handlers_.count(handle)); CHECK_EQ(0u, handlers_.count(handle));
Handler handler_data; Handler handler_data;
handler_data.handler = handler; handler_data.handler = handler;
handler_data.wait_signals = wait_signals; handler_data.wait_signals = wait_signals;
...@@ -186,7 +199,7 @@ void MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) { ...@@ -186,7 +199,7 @@ void MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) {
void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) { void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) {
// TODO(sky): deal with control pipe going bad. // TODO(sky): deal with control pipe going bad.
for (size_t i = 1; i < wait_state.handles.size(); ++i) { for (size_t i = 0; i < wait_state.handles.size(); ++i) {
const MojoResult result = const MojoResult result =
Wait(wait_state.handles[i], wait_state.wait_signals[i], 0); Wait(wait_state.handles[i], wait_state.wait_signals[i], 0);
if (result == MOJO_RESULT_INVALID_ARGUMENT) { if (result == MOJO_RESULT_INVALID_ARGUMENT) {
...@@ -196,9 +209,11 @@ void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) { ...@@ -196,9 +209,11 @@ void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) {
CHECK(false); CHECK(false);
} else if (result == MOJO_RESULT_FAILED_PRECONDITION || } else if (result == MOJO_RESULT_FAILED_PRECONDITION ||
result == MOJO_RESULT_CANCELLED) { result == MOJO_RESULT_CANCELLED) {
CHECK_NE(i, 0u); // Indicates the control pipe went bad.
// Remove the handle first, this way if OnHandleError() tries to remove // Remove the handle first, this way if OnHandleError() tries to remove
// the handle our iterator isn't invalidated. // the handle our iterator isn't invalidated.
DCHECK(handlers_.find(wait_state.handles[i]) != handlers_.end()); CHECK(handlers_.find(wait_state.handles[i]) != handlers_.end());
MessagePumpMojoHandler* handler = MessagePumpMojoHandler* handler =
handlers_[wait_state.handles[i]].handler; handlers_[wait_state.handles[i]].handler;
handlers_.erase(wait_state.handles[i]); handlers_.erase(wait_state.handles[i]);
...@@ -209,9 +224,12 @@ void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) { ...@@ -209,9 +224,12 @@ void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) {
} }
void MessagePumpMojo::SignalControlPipe(const RunState& run_state) { void MessagePumpMojo::SignalControlPipe(const RunState& run_state) {
// TODO(sky): deal with error? const MojoResult result =
WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0, WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0,
MOJO_WRITE_MESSAGE_FLAG_NONE); 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( MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState(
...@@ -230,16 +248,16 @@ MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState( ...@@ -230,16 +248,16 @@ MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState(
MojoDeadline MessagePumpMojo::GetDeadlineForWait( MojoDeadline MessagePumpMojo::GetDeadlineForWait(
const RunState& run_state) const { const RunState& run_state) const {
base::TimeTicks min_time = run_state.delayed_work_time; const base::TimeTicks now(internal::NowTicks());
MojoDeadline deadline = static_cast<MojoDeadline>(0);
if (!run_state.delayed_work_time.is_null())
deadline = TimeTicksToMojoDeadline(run_state.delayed_work_time, now);
for (HandleToHandler::const_iterator i = handlers_.begin(); for (HandleToHandler::const_iterator i = handlers_.begin();
i != handlers_.end(); ++i) { i != handlers_.end(); ++i) {
if (min_time.is_null() && i->second.deadline < min_time) deadline = std::min(
min_time = i->second.deadline; TimeTicksToMojoDeadline(i->second.deadline, now), deadline);
} }
return min_time.is_null() ? MOJO_DEADLINE_INDEFINITE : return deadline;
std::max(static_cast<MojoDeadline>(0),
static_cast<MojoDeadline>(
(min_time - internal::NowTicks()).InMicroseconds()));
} }
} // namespace common } // namespace common
......
...@@ -31,6 +31,7 @@ class MOJO_COMMON_EXPORT MessagePumpMojo : public base::MessagePump { ...@@ -31,6 +31,7 @@ class MOJO_COMMON_EXPORT MessagePumpMojo : public base::MessagePump {
// Registers a MessagePumpMojoHandler for the specified handle. Only one // Registers a MessagePumpMojoHandler for the specified handle. Only one
// handler can be registered for a specified handle. // handler can be registered for a specified handle.
// NOTE: a value of 0 for |deadline| indicates an indefinite timeout.
void AddHandler(MessagePumpMojoHandler* handler, void AddHandler(MessagePumpMojoHandler* handler,
const Handle& handle, const Handle& handle,
MojoHandleSignals wait_signals, MojoHandleSignals wait_signals,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment