Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/common/message_pump_mojo.h" | 5 #include "mojo/common/message_pump_mojo.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 }; | 38 }; |
| 39 | 39 |
| 40 MessagePumpMojo::MessagePumpMojo() : run_state_(NULL) { | 40 MessagePumpMojo::MessagePumpMojo() : run_state_(NULL) { |
| 41 } | 41 } |
| 42 | 42 |
| 43 MessagePumpMojo::~MessagePumpMojo() { | 43 MessagePumpMojo::~MessagePumpMojo() { |
| 44 } | 44 } |
| 45 | 45 |
| 46 void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler, | 46 void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler, |
| 47 MojoHandle handle, | 47 MojoHandle handle, |
| 48 MojoWaitFlags wait_flags) { | 48 MojoWaitFlags wait_flags, |
| 49 base::TimeTicks deadline) { | |
| 49 DCHECK(handler); | 50 DCHECK(handler); |
| 50 DCHECK_NE(MOJO_HANDLE_INVALID, handle); | 51 DCHECK_NE(MOJO_HANDLE_INVALID, handle); |
| 52 Handler old_handler; | |
| 53 if (handlers_.count(handle)) | |
| 54 old_handler = handlers_[handle]; | |
| 51 handlers_[handle].handler = handler; | 55 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.
| |
| 52 handlers_[handle].wait_flags = wait_flags; | 56 handlers_[handle].wait_flags = wait_flags; |
| 53 | 57 handlers_[handle].deadline = deadline; |
| 54 SignalControlPipe(); | 58 if (old_handler.handler) |
| 59 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
| |
| 55 } | 60 } |
| 56 | 61 |
| 57 void MessagePumpMojo::RemoveHandler(MojoHandle handle) { | 62 void MessagePumpMojo::RemoveHandler(MojoHandle handle) { |
| 58 handlers_.erase(handle); | 63 handlers_.erase(handle); |
| 59 SignalControlPipe(); | |
| 60 } | 64 } |
| 61 | 65 |
| 62 void MessagePumpMojo::Run(Delegate* delegate) { | 66 void MessagePumpMojo::Run(Delegate* delegate) { |
| 63 RunState* old_state = run_state_; | 67 RunState* old_state = run_state_; |
| 64 RunState run_state; | 68 RunState run_state; |
| 65 // TODO: better deal with error handling. | 69 // TODO: better deal with error handling. |
| 66 CHECK_NE(run_state.control_pipe.handle_0(), MOJO_HANDLE_INVALID); | 70 CHECK_NE(run_state.control_pipe.handle_0(), MOJO_HANDLE_INVALID); |
| 67 CHECK_NE(run_state.control_pipe.handle_1(), MOJO_HANDLE_INVALID); | 71 CHECK_NE(run_state.control_pipe.handle_1(), MOJO_HANDLE_INVALID); |
| 68 run_state_ = &run_state; | 72 run_state_ = &run_state; |
| 69 bool more_work_is_plausible = true; | 73 bool more_work_is_plausible = true; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 | 112 |
| 109 void MessagePumpMojo::ScheduleDelayedWork( | 113 void MessagePumpMojo::ScheduleDelayedWork( |
| 110 const base::TimeTicks& delayed_work_time) { | 114 const base::TimeTicks& delayed_work_time) { |
| 111 if (!run_state_) | 115 if (!run_state_) |
| 112 return; | 116 return; |
| 113 run_state_->delayed_work_time = delayed_work_time; | 117 run_state_->delayed_work_time = delayed_work_time; |
| 114 SignalControlPipe(); | 118 SignalControlPipe(); |
| 115 } | 119 } |
| 116 | 120 |
| 117 void MessagePumpMojo::DoInternalWork(bool block) { | 121 void MessagePumpMojo::DoInternalWork(bool block) { |
| 118 MojoDeadline deadline; | 122 const MojoDeadline deadline = block ? GetDeadlineForWait() : 0; |
| 119 if (block && !run_state_->delayed_work_time.is_null()) { | |
| 120 const base::TimeDelta delta = run_state_->delayed_work_time - | |
| 121 base::TimeTicks::Now(); | |
| 122 deadline = std::max(static_cast<MojoDeadline>(0), | |
| 123 static_cast<MojoDeadline>(delta.InMicroseconds())); | |
| 124 } else { | |
| 125 deadline = 0; | |
| 126 } | |
| 127 const WaitState wait_state = GetWaitState(); | 123 const WaitState wait_state = GetWaitState(); |
| 128 const MojoResult result = MojoWaitMany( | 124 const MojoResult result = MojoWaitMany( |
| 129 &wait_state.handles.front(), | 125 &wait_state.handles.front(), |
| 130 &wait_state.wait_flags.front(), | 126 &wait_state.wait_flags.front(), |
| 131 static_cast<uint32_t>(wait_state.handles.size()), | 127 static_cast<uint32_t>(wait_state.handles.size()), |
| 132 deadline); | 128 deadline); |
| 133 if (result == 0) { | 129 if (result == 0) { |
| 134 // Control pipe was written to. | 130 // Control pipe was written to. |
| 135 uint32_t num_bytes = 0; | 131 uint32_t num_bytes = 0; |
| 136 MojoReadMessage(run_state_->read_handle(), NULL, &num_bytes, NULL, 0, | 132 MojoReadMessage(run_state_->read_handle(), NULL, &num_bytes, NULL, 0, |
| 137 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); | 133 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); |
| 138 } else if (result > 0) { | 134 } else if (result > 0) { |
| 139 const size_t index = static_cast<size_t>(result); | 135 const size_t index = static_cast<size_t>(result); |
| 140 DCHECK(handlers_.find(wait_state.handles[index]) != handlers_.end()); | 136 DCHECK(handlers_.find(wait_state.handles[index]) != handlers_.end()); |
| 141 handlers_[wait_state.handles[index]].handler->OnHandleReady( | 137 handlers_[wait_state.handles[index]].handler->OnHandleReady( |
| 142 wait_state.handles[index]); | 138 wait_state.handles[index]); |
| 143 } else { | 139 } else { |
| 144 switch (result) { | 140 switch (result) { |
| 145 case MOJO_RESULT_INVALID_ARGUMENT: | 141 case MOJO_RESULT_INVALID_ARGUMENT: |
| 146 case MOJO_RESULT_FAILED_PRECONDITION: | 142 case MOJO_RESULT_FAILED_PRECONDITION: |
| 147 RemoveFirstInvalidHandle(wait_state); | 143 RemoveFirstInvalidHandle(wait_state); |
| 148 break; | 144 break; |
| 149 case MOJO_RESULT_DEADLINE_EXCEEDED: | 145 case MOJO_RESULT_DEADLINE_EXCEEDED: |
| 150 break; | 146 break; |
| 151 default: | 147 default: |
| 152 NOTREACHED(); | 148 NOTREACHED(); |
| 153 } | 149 } |
| 154 } | 150 } |
| 151 | |
| 152 // Notify and remove any handlers whose time has expired. | |
| 153 const base::TimeTicks now(base::TimeTicks::Now()); | |
| 154 for (HandleToHandler::iterator i = handlers_.begin(); i != handlers_.end();) { | |
| 155 if (!i->second.deadline.is_null() && i->second.deadline < now) { | |
| 156 const MojoHandle handle = i->first; | |
| 157 const Handler handler(i->second); | |
| 158 handlers_.erase(i++); | |
| 159 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.
| |
| 160 } else { | |
| 161 ++i; | |
| 162 } | |
| 163 } | |
| 155 } | 164 } |
| 156 | 165 |
| 157 void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) { | 166 void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) { |
| 158 // TODO(sky): deal with control pipe going bad. | 167 // TODO(sky): deal with control pipe going bad. |
| 159 for (size_t i = 1; i < wait_state.handles.size(); ++i) { | 168 for (size_t i = 1; i < wait_state.handles.size(); ++i) { |
| 160 const MojoResult result = | 169 const MojoResult result = |
| 161 MojoWait(wait_state.handles[i], wait_state.wait_flags[i], 0); | 170 MojoWait(wait_state.handles[i], wait_state.wait_flags[i], 0); |
| 162 if (result == MOJO_RESULT_INVALID_ARGUMENT || | 171 if (result == MOJO_RESULT_INVALID_ARGUMENT || |
| 163 result == MOJO_RESULT_FAILED_PRECONDITION) { | 172 result == MOJO_RESULT_FAILED_PRECONDITION) { |
| 173 // Remove the handle first, this way if OnHandleError() tries to remove | |
| 174 // 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.
| |
| 164 DCHECK(handlers_.find(wait_state.handles[i]) != handlers_.end()); | 175 DCHECK(handlers_.find(wait_state.handles[i]) != handlers_.end()); |
| 165 MessagePumpMojoHandler* handler = | 176 MessagePumpMojoHandler* handler = |
| 166 handlers_[wait_state.handles[i]].handler; | 177 handlers_[wait_state.handles[i]].handler; |
| 167 handlers_.erase(wait_state.handles[i]); | 178 handlers_.erase(wait_state.handles[i]); |
| 168 handler->OnHandleError(wait_state.handles[i], result); | 179 handler->OnHandleError(wait_state.handles[i], result); |
| 169 return; | 180 return; |
| 170 } else { | 181 } else { |
| 171 DCHECK_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result); | 182 DCHECK_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result); |
| 172 } | 183 } |
| 173 } | 184 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 188 wait_state.wait_flags.push_back(MOJO_WAIT_FLAG_READABLE); | 199 wait_state.wait_flags.push_back(MOJO_WAIT_FLAG_READABLE); |
| 189 | 200 |
| 190 for (HandleToHandler::const_iterator i = handlers_.begin(); | 201 for (HandleToHandler::const_iterator i = handlers_.begin(); |
| 191 i != handlers_.end(); ++i) { | 202 i != handlers_.end(); ++i) { |
| 192 wait_state.handles.push_back(i->first); | 203 wait_state.handles.push_back(i->first); |
| 193 wait_state.wait_flags.push_back(i->second.wait_flags); | 204 wait_state.wait_flags.push_back(i->second.wait_flags); |
| 194 } | 205 } |
| 195 return wait_state; | 206 return wait_state; |
| 196 } | 207 } |
| 197 | 208 |
| 209 MojoDeadline MessagePumpMojo::GetDeadlineForWait() const { | |
| 210 base::TimeTicks min_time = run_state_->delayed_work_time; | |
| 211 for (HandleToHandler::const_iterator i = handlers_.begin(); | |
| 212 i != handlers_.end(); ++i) { | |
| 213 if (min_time.is_null() && i->second.deadline < min_time) | |
| 214 min_time = i->second.deadline; | |
| 215 } | |
| 216 return min_time.is_null() ? MOJO_DEADLINE_INDEFINITE : | |
| 217 std::max(static_cast<MojoDeadline>(0), | |
| 218 static_cast<MojoDeadline>( | |
| 219 (min_time - base::TimeTicks::Now()).InMicroseconds())); | |
| 220 } | |
| 221 | |
| 198 } // namespace common | 222 } // namespace common |
| 199 } // namespace mojo | 223 } // namespace mojo |
| OLD | NEW |