| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "content/common/message_port.h" | 5 #include "content/common/message_port.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/threading/thread_task_runner_handle.h" | 9 #include "base/threading/thread_task_runner_handle.h" |
| 10 | 10 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 } | 146 } |
| 147 | 147 |
| 148 void MessagePort::State::AddWatch() { | 148 void MessagePort::State::AddWatch() { |
| 149 if (!callback_) | 149 if (!callback_) |
| 150 return; | 150 return; |
| 151 | 151 |
| 152 DCHECK(!watcher_handle_.is_valid()); | 152 DCHECK(!watcher_handle_.is_valid()); |
| 153 MojoResult rv = CreateWatcher(&State::CallOnHandleReady, &watcher_handle_); | 153 MojoResult rv = CreateWatcher(&State::CallOnHandleReady, &watcher_handle_); |
| 154 DCHECK_EQ(MOJO_RESULT_OK, rv); | 154 DCHECK_EQ(MOJO_RESULT_OK, rv); |
| 155 | 155 |
| 156 // We use a scoped_refptr<State> instance as the watch context. This is owned | 156 // Balanced in CallOnHandleReady when MOJO_RESULT_CANCELLED is received. |
| 157 // by the watch and deleted upon receiving a cancellation notification. | 157 AddRef(); |
| 158 scoped_refptr<State>* state_ref = new scoped_refptr<State>(this); | |
| 159 context_ = reinterpret_cast<uintptr_t>(state_ref); | |
| 160 | 158 |
| 161 // NOTE: An HTML MessagePort does not receive an event to tell it when the | 159 // NOTE: An HTML MessagePort does not receive an event to tell it when the |
| 162 // peer has gone away, so we only watch for readability here. | 160 // peer has gone away, so we only watch for readability here. |
| 163 rv = MojoWatch(watcher_handle_.get().value(), handle_.get().value(), | 161 rv = |
| 164 MOJO_HANDLE_SIGNAL_READABLE, context_); | 162 MojoWatch(watcher_handle_.get().value(), handle_.get().value(), |
| 163 MOJO_HANDLE_SIGNAL_READABLE, reinterpret_cast<uintptr_t>(this)); |
| 165 DCHECK_EQ(MOJO_RESULT_OK, rv); | 164 DCHECK_EQ(MOJO_RESULT_OK, rv); |
| 166 | 165 |
| 167 ArmWatcher(); | 166 ArmWatcher(); |
| 168 } | 167 } |
| 169 | 168 |
| 170 void MessagePort::State::CancelWatch() { | 169 void MessagePort::State::CancelWatch() { |
| 171 watcher_handle_.reset(); | 170 watcher_handle_.reset(); |
| 172 context_ = 0; | |
| 173 } | 171 } |
| 174 | 172 |
| 175 MessagePort::State::~State() = default; | 173 MessagePort::State::~State() = default; |
| 176 | 174 |
| 177 void MessagePort::State::ArmWatcher() { | 175 void MessagePort::State::ArmWatcher() { |
| 178 if (!watcher_handle_.is_valid()) | 176 if (!watcher_handle_.is_valid()) |
| 179 return; | 177 return; |
| 180 | 178 |
| 181 uint32_t num_ready_contexts = 1; | 179 uint32_t num_ready_contexts = 1; |
| 182 uintptr_t ready_context; | 180 uintptr_t ready_context; |
| 183 MojoResult ready_result; | 181 MojoResult ready_result; |
| 184 MojoHandleSignalsState ready_state; | 182 MojoHandleSignalsState ready_state; |
| 185 MojoResult rv = | 183 MojoResult rv = |
| 186 MojoArmWatcher(watcher_handle_.get().value(), &num_ready_contexts, | 184 MojoArmWatcher(watcher_handle_.get().value(), &num_ready_contexts, |
| 187 &ready_context, &ready_result, &ready_state); | 185 &ready_context, &ready_result, &ready_state); |
| 188 if (rv == MOJO_RESULT_OK) | 186 if (rv == MOJO_RESULT_OK) |
| 189 return; | 187 return; |
| 190 | 188 |
| 191 // The watcher could not be armed because it would notify immediately. | 189 // The watcher could not be armed because it would notify immediately. |
| 192 DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv); | 190 DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv); |
| 193 DCHECK_EQ(1u, num_ready_contexts); | 191 DCHECK_EQ(1u, num_ready_contexts); |
| 194 DCHECK_EQ(context_, ready_context); | 192 DCHECK_EQ(reinterpret_cast<uintptr_t>(this), ready_context); |
| 195 | 193 |
| 196 if (ready_result == MOJO_RESULT_OK) { | 194 if (ready_result == MOJO_RESULT_OK) { |
| 197 // The handle is already signaled, so we trigger a callback now. | 195 // The handle is already signaled, so we trigger a callback now. |
| 198 base::ThreadTaskRunnerHandle::Get()->PostTask( | 196 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 199 FROM_HERE, base::Bind(&State::OnHandleReady, this, MOJO_RESULT_OK)); | 197 FROM_HERE, base::Bind(&State::OnHandleReady, this, MOJO_RESULT_OK)); |
| 200 return; | 198 return; |
| 201 } | 199 } |
| 202 | 200 |
| 203 if (ready_result == MOJO_RESULT_FAILED_PRECONDITION) { | 201 if (ready_result == MOJO_RESULT_FAILED_PRECONDITION) { |
| 204 DVLOG(1) << this << " MojoArmWatcher failed because of a broken pipe."; | 202 DVLOG(1) << this << " MojoArmWatcher failed because of a broken pipe."; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 215 } else { | 213 } else { |
| 216 // And now his watch is ended. | 214 // And now his watch is ended. |
| 217 } | 215 } |
| 218 } | 216 } |
| 219 | 217 |
| 220 // static | 218 // static |
| 221 void MessagePort::State::CallOnHandleReady(uintptr_t context, | 219 void MessagePort::State::CallOnHandleReady(uintptr_t context, |
| 222 MojoResult result, | 220 MojoResult result, |
| 223 MojoHandleSignalsState signals_state, | 221 MojoHandleSignalsState signals_state, |
| 224 MojoWatcherNotificationFlags flags) { | 222 MojoWatcherNotificationFlags flags) { |
| 225 auto* state_ref = reinterpret_cast<scoped_refptr<State>*>(context); | 223 auto* state = reinterpret_cast<State*>(context); |
| 226 if (result == MOJO_RESULT_CANCELLED) { | 224 if (result == MOJO_RESULT_CANCELLED) { |
| 227 // Last notification. Delete the watch's owned State ref. | 225 // Last notification. Release the watch context's owned State ref. This is |
| 228 delete state_ref; | 226 // balanced in MessagePort::State::AddWatch. |
| 227 state->Release(); |
| 229 } else { | 228 } else { |
| 230 (*state_ref)->OnHandleReady(result); | 229 state->OnHandleReady(result); |
| 231 } | 230 } |
| 232 } | 231 } |
| 233 | 232 |
| 234 } // namespace content | 233 } // namespace content |
| OLD | NEW |