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..16396720a5aca9cd9aebcd9316b4f085fb1a6949 100644 |
--- a/mojo/common/message_pump_mojo.cc |
+++ b/mojo/common/message_pump_mojo.cc |
@@ -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); |
+ Handler old_handler; |
+ if (handlers_.count(handle)) |
+ old_handler = handlers_[handle]; |
handlers_[handle].handler = handler; |
darin (slow to review)
2013/11/21 18:14:52
nit: it'd probably be worth optimizing this code t
sky
2013/11/22 19:39:44
Done.
|
handlers_[handle].wait_flags = wait_flags; |
- |
- SignalControlPipe(); |
+ handlers_[handle].deadline = deadline; |
+ if (old_handler.handler) |
+ old_handler.handler->OnHandleError(handle, MOJO_RESULT_CANCELLED); |
darin (slow to review)
2013/11/21 18:14:52
I'm a little bit worried about calling OnHandleErr
sky
2013/11/22 19:39:44
As discussed I made this DCHECK that there isn't a
|
} |
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,19 @@ void MessagePumpMojo::DoInternalWork(bool block) { |
NOTREACHED(); |
} |
} |
+ |
+ // Notify and remove any handlers whose time has expired. |
+ const base::TimeTicks now(base::TimeTicks::Now()); |
+ for (HandleToHandler::iterator i = handlers_.begin(); i != handlers_.end();) { |
+ if (!i->second.deadline.is_null() && i->second.deadline < now) { |
+ const MojoHandle handle = i->first; |
+ const Handler handler(i->second); |
+ handlers_.erase(i++); |
+ handler.handler->OnHandleError(handle, MOJO_RESULT_DEADLINE_EXCEEDED); |
darin (slow to review)
2013/11/21 18:14:52
OnHandleError can call AddHandler or RemoveHandler
sky
2013/11/22 19:39:44
Done.
|
+ } else { |
+ ++i; |
+ } |
+ } |
} |
void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) { |
@@ -161,6 +170,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 too our iterator isn't invalidated. |
darin (slow to review)
2013/11/21 18:14:52
nit: too -> to
sky
2013/11/22 19:39:44
Done.
|
DCHECK(handlers_.find(wait_state.handles[i]) != handlers_.end()); |
MessagePumpMojoHandler* handler = |
handlers_[wait_state.handles[i]].handler; |
@@ -195,5 +206,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 |