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

Unified Diff: mojo/common/message_pump_mojo.cc

Issue 69883008: Implements HandleWatcher in terms of MessagePumpMojo (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add id to detect whether should notify Created 7 years, 1 month 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/common/message_pump_mojo.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/common/message_pump_mojo.cc
diff --git a/mojo/common/message_pump_mojo.cc b/mojo/common/message_pump_mojo.cc
index 7b5b16302c07dbdb6864adc907717a474dabbd33..64e1396f874b24320103a4979e35274422fa7e1a 100644
--- a/mojo/common/message_pump_mojo.cc
+++ b/mojo/common/message_pump_mojo.cc
@@ -37,7 +37,7 @@ struct MessagePumpMojo::RunState {
bool should_quit;
};
-MessagePumpMojo::MessagePumpMojo() : run_state_(NULL) {
+MessagePumpMojo::MessagePumpMojo() : run_state_(NULL), next_handler_id_(0) {
}
MessagePumpMojo::~MessagePumpMojo() {
@@ -45,18 +45,22 @@ MessagePumpMojo::~MessagePumpMojo() {
void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler,
MojoHandle handle,
- MojoWaitFlags wait_flags) {
+ MojoWaitFlags wait_flags,
+ base::TimeTicks deadline) {
DCHECK(handler);
DCHECK_NE(MOJO_HANDLE_INVALID, handle);
- handlers_[handle].handler = handler;
- handlers_[handle].wait_flags = wait_flags;
-
- SignalControlPipe();
+ // Assume it's an error if someone tries to reregister an existing handle.
+ DCHECK_EQ(0u, handlers_.count(handle));
+ Handler handler_data;
+ handler_data.handler = handler;
+ handler_data.wait_flags = wait_flags;
+ handler_data.deadline = deadline;
+ handler_data.id = next_handler_id_++;
+ handlers_[handle] = handler_data;
}
void MessagePumpMojo::RemoveHandler(MojoHandle handle) {
handlers_.erase(handle);
- SignalControlPipe();
}
void MessagePumpMojo::Run(Delegate* delegate) {
@@ -115,15 +119,7 @@ void MessagePumpMojo::ScheduleDelayedWork(
}
void MessagePumpMojo::DoInternalWork(bool block) {
- MojoDeadline deadline;
- if (block && !run_state_->delayed_work_time.is_null()) {
- const base::TimeDelta delta = run_state_->delayed_work_time -
- base::TimeTicks::Now();
- deadline = std::max(static_cast<MojoDeadline>(0),
- static_cast<MojoDeadline>(delta.InMicroseconds()));
- } else {
- deadline = 0;
- }
+ const MojoDeadline deadline = block ? GetDeadlineForWait() : 0;
const WaitState wait_state = GetWaitState();
const MojoResult result = MojoWaitMany(
&wait_state.handles.front(),
@@ -152,6 +148,21 @@ void MessagePumpMojo::DoInternalWork(bool block) {
NOTREACHED();
}
}
+
+ // 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_);
+ const base::TimeTicks now(base::TimeTicks::Now());
+ for (HandleToHandler::const_iterator i = cloned_handlers.begin();
+ i != 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 &&
+ handlers_.find(i->first) != handlers_.end() &&
+ handlers_[i->first].id == i->second.id) {
+ i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED);
+ }
+ }
}
void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) {
@@ -161,6 +172,8 @@ void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) {
MojoWait(wait_state.handles[i], wait_state.wait_flags[i], 0);
if (result == MOJO_RESULT_INVALID_ARGUMENT ||
result == MOJO_RESULT_FAILED_PRECONDITION) {
+ // Remove the handle first, this way if OnHandleError() tries to remove
+ // the handle our iterator isn't invalidated.
DCHECK(handlers_.find(wait_state.handles[i]) != handlers_.end());
MessagePumpMojoHandler* handler =
handlers_[wait_state.handles[i]].handler;
@@ -195,5 +208,18 @@ MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState() const {
return wait_state;
}
+MojoDeadline MessagePumpMojo::GetDeadlineForWait() const {
+ base::TimeTicks min_time = run_state_->delayed_work_time;
+ for (HandleToHandler::const_iterator i = handlers_.begin();
+ i != handlers_.end(); ++i) {
+ if (min_time.is_null() && i->second.deadline < min_time)
+ min_time = i->second.deadline;
+ }
+ return min_time.is_null() ? MOJO_DEADLINE_INDEFINITE :
+ std::max(static_cast<MojoDeadline>(0),
+ static_cast<MojoDeadline>(
+ (min_time - base::TimeTicks::Now()).InMicroseconds()));
+}
+
} // namespace common
} // namespace mojo
« no previous file with comments | « mojo/common/message_pump_mojo.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698