| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/edk/system/wait_set_dispatcher.h" | 5 #include "mojo/edk/system/wait_set_dispatcher.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "mojo/edk/system/configuration.h" | 10 #include "mojo/edk/system/configuration.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 // invasive changes in many other places. We really count on |Dispatcher| not | 117 // invasive changes in many other places. We really count on |Dispatcher| not |
| 118 // doing anything interesting after calling |CloseImplNoLock()|, and since | 118 // doing anything interesting after calling |CloseImplNoLock()|, and since |
| 119 // |CloseImplNoLock()| is allowed to do nothing all the lock invariants are | 119 // |CloseImplNoLock()| is allowed to do nothing all the lock invariants are |
| 120 // satisfied. | 120 // satisfied. |
| 121 DCHECK(is_closed_no_lock()); | 121 DCHECK(is_closed_no_lock()); |
| 122 mutex().Unlock(); | 122 mutex().Unlock(); |
| 123 | 123 |
| 124 for (auto& p : entries) { | 124 for (auto& p : entries) { |
| 125 const auto& entry = p.second; | 125 const auto& entry = p.second; |
| 126 if (entry->dispatcher) | 126 if (entry->dispatcher) |
| 127 entry->dispatcher->RemoveAwakableWithContext(this, entry->cookie, | 127 entry->dispatcher->RemoveAwakable(true, this, entry->cookie, nullptr); |
| 128 nullptr); | |
| 129 } | 128 } |
| 130 | 129 |
| 131 // The caller of |CloseImplNoLock()| expects |mutex()| to be locked, so we | 130 // The caller of |CloseImplNoLock()| expects |mutex()| to be locked, so we |
| 132 // have to re-lock it (even though it really should do nothing afterwards). | 131 // have to re-lock it (even though it really should do nothing afterwards). |
| 133 mutex().Lock(); | 132 mutex().Lock(); |
| 134 } | 133 } |
| 135 | 134 |
| 136 RefPtr<Dispatcher> | 135 RefPtr<Dispatcher> |
| 137 WaitSetDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock( | 136 WaitSetDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock( |
| 138 MessagePipe* /*message_pipe*/, | 137 MessagePipe* /*message_pipe*/, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 163 if (entries_.size() >= GetConfiguration().max_wait_set_num_entries) | 162 if (entries_.size() >= GetConfiguration().max_wait_set_num_entries) |
| 164 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 163 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 165 // Note: We'll have to set the entry's dispatcher later. | 164 // Note: We'll have to set the entry's dispatcher later. |
| 166 entry = new Entry(signals, cookie); | 165 entry = new Entry(signals, cookie); |
| 167 entries_[cookie] = std::unique_ptr<Entry>(entry); | 166 entries_[cookie] = std::unique_ptr<Entry>(entry); |
| 168 | 167 |
| 169 is_busy_ = true; | 168 is_busy_ = true; |
| 170 } | 169 } |
| 171 | 170 |
| 172 HandleSignalsState signals_state; | 171 HandleSignalsState signals_state; |
| 173 MojoResult result = dispatcher->AddAwakableUnconditional( | 172 MojoResult result = |
| 174 this, signals, cookie, &signals_state); | 173 dispatcher->AddAwakable(this, cookie, true, signals, &signals_state); |
| 175 | 174 |
| 176 // Can't use |MutexLocker|, since we need to do some work outside the lock | 175 // Can't use |MutexLocker|, since we need to do some work outside the lock |
| 177 // in some code paths. | 176 // in some code paths. |
| 178 mutex().Lock(); | 177 mutex().Lock(); |
| 179 DCHECK(is_busy_); | 178 DCHECK(is_busy_); |
| 180 is_busy_ = false; | 179 is_busy_ = false; |
| 181 | 180 |
| 182 // Note: We may have been closed while |mutex()| was unlocked, so we have to | 181 // Note: We may have been closed while |mutex()| was unlocked, so we have to |
| 183 // check again! | 182 // check again! |
| 184 if (is_closed_no_lock()) { | 183 if (is_closed_no_lock()) { |
| 185 // Warning: In this case, |entry| has been invalidated, since it was owned | 184 // Warning: In this case, |entry| has been invalidated, since it was owned |
| 186 // by |entries_|. | 185 // by |entries_|. |
| 187 DCHECK(entries_.empty()); | 186 DCHECK(entries_.empty()); |
| 188 mutex().Unlock(); | 187 mutex().Unlock(); |
| 189 if (result == MOJO_RESULT_OK || result == MOJO_RESULT_ALREADY_EXISTS) { | 188 if (result == MOJO_RESULT_OK || result == MOJO_RESULT_ALREADY_EXISTS) { |
| 190 // We have to remove ourself from the target dispatcher's awakable list. | 189 // We have to remove ourself from the target dispatcher's awakable list. |
| 191 dispatcher->RemoveAwakableWithContext(this, cookie, nullptr); | 190 dispatcher->RemoveAwakable(true, this, cookie, nullptr); |
| 192 } | 191 } |
| 193 return MOJO_RESULT_INVALID_ARGUMENT; | 192 return MOJO_RESULT_INVALID_ARGUMENT; |
| 194 } | 193 } |
| 195 | 194 |
| 196 DCHECK(entries_.find(cookie) != entries_.end()); | 195 DCHECK(entries_.find(cookie) != entries_.end()); |
| 197 DCHECK_EQ(entries_[cookie].get(), entry); | 196 DCHECK_EQ(entries_[cookie].get(), entry); |
| 198 | 197 |
| 199 if (result == MOJO_RESULT_ALREADY_EXISTS) { | 198 if (result == MOJO_RESULT_ALREADY_EXISTS) { |
| 200 // It was added, but the wait condition is already satisfied. | 199 // It was added, but the wait condition is already satisfied. |
| 201 AddPossiblyTriggeredNoLock(entry, Entry::TriggerState::POSSIBLY_SATISFIED); | 200 AddPossiblyTriggeredNoLock(entry, Entry::TriggerState::POSSIBLY_SATISFIED); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 dispatcher = std::move(entry->dispatcher); | 235 dispatcher = std::move(entry->dispatcher); |
| 237 | 236 |
| 238 if (entry->trigger_state != Entry::TriggerState::NOT_TRIGGERED) | 237 if (entry->trigger_state != Entry::TriggerState::NOT_TRIGGERED) |
| 239 RemovePossiblyTriggeredNoLock(entry); | 238 RemovePossiblyTriggeredNoLock(entry); |
| 240 | 239 |
| 241 // Note: This invalidates |entry|. | 240 // Note: This invalidates |entry|. |
| 242 entries_.erase(it); | 241 entries_.erase(it); |
| 243 } | 242 } |
| 244 | 243 |
| 245 if (dispatcher) | 244 if (dispatcher) |
| 246 dispatcher->RemoveAwakableWithContext(this, cookie, nullptr); | 245 dispatcher->RemoveAwakable(true, this, cookie, nullptr); |
| 247 return MOJO_RESULT_OK; | 246 return MOJO_RESULT_OK; |
| 248 } | 247 } |
| 249 | 248 |
| 250 MojoResult WaitSetDispatcher::WaitSetWaitImpl( | 249 MojoResult WaitSetDispatcher::WaitSetWaitImpl( |
| 251 MojoDeadline deadline, | 250 MojoDeadline deadline, |
| 252 UserPointer<uint32_t> num_results, | 251 UserPointer<uint32_t> num_results, |
| 253 UserPointer<MojoWaitSetResult> results, | 252 UserPointer<MojoWaitSetResult> results, |
| 254 UserPointer<uint32_t> max_results) { | 253 UserPointer<uint32_t> max_results) { |
| 255 MutexLocker locker(&mutex()); | 254 MutexLocker locker(&mutex()); |
| 256 if (is_closed_no_lock()) | 255 if (is_closed_no_lock()) |
| 257 return MOJO_RESULT_INVALID_ARGUMENT; | 256 return MOJO_RESULT_INVALID_ARGUMENT; |
| 258 | 257 |
| 259 // TODO(vtl) | 258 // TODO(vtl) |
| 260 NOTIMPLEMENTED(); | 259 NOTIMPLEMENTED(); |
| 261 return MOJO_RESULT_UNIMPLEMENTED; | 260 return MOJO_RESULT_UNIMPLEMENTED; |
| 262 } | 261 } |
| 263 | 262 |
| 264 bool WaitSetDispatcher::Awake(uint64_t context, | 263 bool WaitSetDispatcher::Awake(uint64_t context, |
| 265 AwakeReason reason, | 264 AwakeReason reason, |
| 266 const HandleSignalsState& signals_state) { | 265 const HandleSignalsState& signals_state) { |
| 267 MutexLocker locker(&mutex()); | 266 MutexLocker locker(&mutex()); |
| 268 | 267 |
| 269 if (is_closed_no_lock()) { | 268 if (is_closed_no_lock()) { |
| 270 // See |CloseImplNoLock()|: This case may occur while we're unlocked in | 269 // See |CloseImplNoLock()|: This case may occur while we're unlocked in |
| 271 // |CloseImplNoLock()| (after that, we will have been removed from all the | 270 // |CloseImplNoLock()| (after that, we will have been removed from all the |
| 272 // awakable lists, so |Awake()| should no longer be called). We may as well | 271 // awakable lists, so |Awake()| should no longer be called). We may as well |
| 273 // return false here, which will automatically remove ourselves from the | 272 // return false here, which will automatically remove ourselves from the |
| 274 // awakable list (|CloseImplNoLock()| will call | 273 // awakable list (|CloseImplNoLock()| will call |RemoveAwakable()| anyway, |
| 275 // |RemoveAwakableWithContext()| anyway, but that's OK). | 274 // but that's OK). |
| 276 return false; | 275 return false; |
| 277 } | 276 } |
| 278 | 277 |
| 279 auto it = entries_.find(context); | 278 auto it = entries_.find(context); |
| 280 DCHECK(it != entries_.end()); | 279 DCHECK(it != entries_.end()); |
| 281 const auto& entry = it->second; | 280 const auto& entry = it->second; |
| 282 switch (reason) { | 281 switch (reason) { |
| 283 case AwakeReason::SATISFIED: | 282 case AwakeReason::SATISFIED: |
| 284 if (entry->trigger_state == Entry::TriggerState::NOT_TRIGGERED) { | 283 if (entry->trigger_state == Entry::TriggerState::NOT_TRIGGERED) { |
| 285 AddPossiblyTriggeredNoLock(entry.get(), | 284 AddPossiblyTriggeredNoLock(entry.get(), |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 entry->possibly_triggered_next->possibly_triggered_previous = | 366 entry->possibly_triggered_next->possibly_triggered_previous = |
| 368 entry->possibly_triggered_previous; | 367 entry->possibly_triggered_previous; |
| 369 } | 368 } |
| 370 | 369 |
| 371 entry->possibly_triggered_previous = nullptr; | 370 entry->possibly_triggered_previous = nullptr; |
| 372 entry->possibly_triggered_next = nullptr; | 371 entry->possibly_triggered_next = nullptr; |
| 373 } | 372 } |
| 374 | 373 |
| 375 } // namespace system | 374 } // namespace system |
| 376 } // namespace mojo | 375 } // namespace mojo |
| OLD | NEW |