| 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 #ifndef MOJO_EDK_SYSTEM_WAIT_SET_DISPATCHER_H_ | 5 #ifndef MOJO_EDK_SYSTEM_WAIT_SET_DISPATCHER_H_ |
| 6 #define MOJO_EDK_SYSTEM_WAIT_SET_DISPATCHER_H_ | 6 #define MOJO_EDK_SYSTEM_WAIT_SET_DISPATCHER_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "mojo/edk/system/awakable.h" | 11 #include "mojo/edk/system/awakable.h" |
| 12 #include "mojo/edk/system/dispatcher.h" | 12 #include "mojo/edk/system/dispatcher.h" |
| 13 #include "mojo/edk/util/cond_var.h" |
| 13 #include "mojo/edk/util/ref_ptr.h" | 14 #include "mojo/edk/util/ref_ptr.h" |
| 14 #include "mojo/edk/util/thread_annotations.h" | 15 #include "mojo/edk/util/thread_annotations.h" |
| 15 #include "mojo/public/cpp/system/macros.h" | 16 #include "mojo/public/cpp/system/macros.h" |
| 16 | 17 |
| 17 namespace mojo { | 18 namespace mojo { |
| 18 namespace system { | 19 namespace system { |
| 19 | 20 |
| 20 // This is the |Dispatcher| implementation for wait sets (created by the Mojo | 21 // This is the |Dispatcher| implementation for wait sets (created by the Mojo |
| 21 // primitive |MojoCreateWaitSet()|). This class is thread-safe. | 22 // primitive |MojoCreateWaitSet()|). This class is thread-safe. |
| 22 // TODO(vtl): We rely on |Dispatcher| itself never acquiring any other mutex | 23 // TODO(vtl): We rely on |Dispatcher| itself never acquiring any other mutex |
| 23 // under |mutex()|. We should specify (and double-check) this requirement. | 24 // under |mutex()|. We should specify (and double-check) this requirement. |
| 24 class WaitSetDispatcher final : public Dispatcher, public Awakable { | 25 class WaitSetDispatcher final : public Dispatcher, public Awakable { |
| 25 public: | 26 public: |
| 26 // The default/standard rights for a wait set handle. Note that they are not | 27 // The default/standard rights for a wait set handle. Note that wait set |
| 27 // transferrable. | 28 // handles are not transferrable. |
| 28 // TODO(vtl): Figure out if these are the correct rights. (E.g., we currently | 29 // TODO(vtl): Figure out if these are the correct rights. (E.g., we currently |
| 29 // don't have get/set options functions ... but maybe we should?) | 30 // don't have get/set options functions ... but maybe we should?) |
| 30 static constexpr MojoHandleRights kDefaultHandleRights = | 31 static constexpr MojoHandleRights kDefaultHandleRights = |
| 31 MOJO_HANDLE_RIGHT_READ | MOJO_HANDLE_RIGHT_WRITE | | 32 MOJO_HANDLE_RIGHT_READ | MOJO_HANDLE_RIGHT_WRITE | |
| 32 MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS; | 33 MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS; |
| 33 | 34 |
| 34 // The default options to use for |MojoCreateWaitSet()|. (Real uses should | 35 // The default options to use for |MojoCreateWaitSet()|. (Real uses should |
| 35 // obtain this via |ValidateCreateOptions()| with a null |in_options|; this is | 36 // obtain this via |ValidateCreateOptions()| with a null |in_options|; this is |
| 36 // exposed directly for testing convenience.) | 37 // exposed directly for testing convenience.) |
| 37 static const MojoCreateWaitSetOptions kDefaultCreateOptions; | 38 static const MojoCreateWaitSetOptions kDefaultCreateOptions; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 // if the dispatcher was closed. | 72 // if the dispatcher was closed. |
| 72 util::RefPtr<Dispatcher> dispatcher; | 73 util::RefPtr<Dispatcher> dispatcher; |
| 73 const MojoHandleSignals signals; | 74 const MojoHandleSignals signals; |
| 74 const uint64_t cookie; | 75 const uint64_t cookie; |
| 75 | 76 |
| 76 // This is false until |WaitSetDispatcher::WaitSetAddImpl()| is "finished" | 77 // This is false until |WaitSetDispatcher::WaitSetAddImpl()| is "finished" |
| 77 // adding it. |...::WaitSetRemoveImpl()| won't acknowledge the existence of | 78 // adding it. |...::WaitSetRemoveImpl()| won't acknowledge the existence of |
| 78 // this entry until this is true. | 79 // this entry until this is true. |
| 79 bool ready = false; | 80 bool ready = false; |
| 80 | 81 |
| 82 // This is set only "inside" |WaitSetDispatcher::WaitSetRemoveImpl()|: Since |
| 83 // we can only call |dispatcher|'s |RemoveAwakable()| with |mutex()| |
| 84 // unlocked, we may get awoken before that happens. So instead of removing |
| 85 // the entry from |entries_| immediately, we first set this to true under |
| 86 // |mutex()|, unlock and call |RemoveAwakable()|, and then reacquire |
| 87 // |mutex()| and actually remove the entry. |
| 88 bool is_being_removed = false; |
| 89 |
| 81 HandleSignalsState signals_state; | 90 HandleSignalsState signals_state; |
| 82 bool is_triggered = false; | 91 bool is_triggered = false; |
| 83 | 92 |
| 84 // Only meaningful if |is_triggered| is true. This is used to maintain a | 93 // Only meaningful if |is_triggered| is true. This is used to maintain a |
| 85 // doubly linked list of entries that are triggered (for various reasons: | 94 // doubly linked list of entries that are triggered (for various reasons: |
| 86 // being satisfied, being never-satisfiable, being cancelled/closed). | 95 // being satisfied, being never-satisfiable, being cancelled/closed). |
| 87 // |triggered_previous| and |triggered_next| are null if |this| is equal to | 96 // |triggered_previous| and |triggered_next| are null if |this| is equal to |
| 88 // |WaitSetDispatcher::triggered_head_| and | 97 // |WaitSetDispatcher::triggered_head_| and |
| 89 // |WaitSetDispatcher::triggered_tail_|, respectively. | 98 // |WaitSetDispatcher::triggered_tail_|, respectively. |
| 90 Entry* triggered_previous = nullptr; | 99 Entry* triggered_previous = nullptr; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 111 | 120 |
| 112 // |Awakable| implementation: | 121 // |Awakable| implementation: |
| 113 void Awake(uint64_t context, | 122 void Awake(uint64_t context, |
| 114 AwakeReason reason, | 123 AwakeReason reason, |
| 115 const HandleSignalsState& signals_state) override; | 124 const HandleSignalsState& signals_state) override; |
| 116 | 125 |
| 117 void AddTriggeredNoLock(Entry* entry) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex()); | 126 void AddTriggeredNoLock(Entry* entry) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex()); |
| 118 void RemoveTriggeredNoLock(Entry* entry) | 127 void RemoveTriggeredNoLock(Entry* entry) |
| 119 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex()); | 128 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex()); |
| 120 | 129 |
| 130 // Associated to |mutex_|. This should be signaled when |triggered_count_| |
| 131 // becomes nonzero or this dispatcher is closed. |
| 132 util::CondVar cv_; |
| 133 |
| 121 // Map of cookies to entries. | 134 // Map of cookies to entries. |
| 122 using CookieToEntryMap = std::map<uint64_t, std::unique_ptr<Entry>>; | 135 using CookieToEntryMap = std::map<uint64_t, std::unique_ptr<Entry>>; |
| 123 CookieToEntryMap entries_ MOJO_GUARDED_BY(mutex()); | 136 CookieToEntryMap entries_ MOJO_GUARDED_BY(mutex()); |
| 124 | 137 |
| 125 // Intrusive "doubly linked list" (via cookies) of entries that are triggered. | 138 // Intrusive "doubly linked list" (via cookies) of entries that are triggered. |
| 126 Entry* triggered_head_ MOJO_GUARDED_BY(mutex()) = nullptr; | 139 Entry* triggered_head_ MOJO_GUARDED_BY(mutex()) = nullptr; |
| 127 Entry* triggered_tail_ MOJO_GUARDED_BY(mutex()) = nullptr; | 140 Entry* triggered_tail_ MOJO_GUARDED_BY(mutex()) = nullptr; |
| 128 // Size of the above list. | 141 // Size of the above list. |
| 129 size_t triggered_count_ MOJO_GUARDED_BY(mutex()) = 0u; | 142 size_t triggered_count_ MOJO_GUARDED_BY(mutex()) = 0u; |
| 130 | 143 |
| 131 MOJO_DISALLOW_COPY_AND_ASSIGN(WaitSetDispatcher); | 144 MOJO_DISALLOW_COPY_AND_ASSIGN(WaitSetDispatcher); |
| 132 }; | 145 }; |
| 133 | 146 |
| 134 } // namespace system | 147 } // namespace system |
| 135 } // namespace mojo | 148 } // namespace mojo |
| 136 | 149 |
| 137 #endif // MOJO_EDK_SYSTEM_WAIT_SET_DISPATCHER_H_ | 150 #endif // MOJO_EDK_SYSTEM_WAIT_SET_DISPATCHER_H_ |
| OLD | NEW |