| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_ |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <deque> | 10 #include <deque> |
| 11 #include <map> | 11 #include <map> |
| 12 #include <queue> |
| 12 | 13 |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 15 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
| 16 #include "base/memory/ref_counted_delete_on_message_loop.h" | 17 #include "base/memory/ref_counted_delete_on_message_loop.h" |
| 17 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
| 18 #include "base/memory/weak_ptr.h" | 19 #include "base/memory/weak_ptr.h" |
| 19 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
| 20 #include "base/threading/thread_checker.h" | 21 #include "base/threading/thread_checker.h" |
| 21 #include "mojo/public/cpp/bindings/callback.h" | 22 #include "mojo/public/cpp/bindings/callback.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 32 } | 33 } |
| 33 | 34 |
| 34 namespace mojo { | 35 namespace mojo { |
| 35 | 36 |
| 36 class AssociatedGroup; | 37 class AssociatedGroup; |
| 37 | 38 |
| 38 namespace internal { | 39 namespace internal { |
| 39 | 40 |
| 40 class InterfaceEndpointClient; | 41 class InterfaceEndpointClient; |
| 41 | 42 |
| 43 class InterfaceEndpointController { |
| 44 public: |
| 45 virtual ~InterfaceEndpointController() {} |
| 46 |
| 47 virtual bool SendMessage(Message* message) = 0; |
| 48 |
| 49 virtual void AllowWokenUpBySyncWatchOnSameThread() = 0; |
| 50 /* |
| 51 // Requests to register |message_pipe_| with SyncHandleWatcher whenever this |
| 52 // instance is expecting incoming messages. |
| 53 // |
| 54 // Please note that UnregisterSyncHandleWatch() needs to be called as many |
| 55 // times as successful RegisterSyncHandleWatch() calls in order to cancel the |
| 56 // effect. |
| 57 virtual bool RegisterSyncHandleWatch() = 0; |
| 58 virtual void UnregisterSyncHandleWatch() = 0;*/ |
| 59 |
| 60 // Watches all handles registered with SyncHandleWatcher on the same thread. |
| 61 // The method returns true when |*should_stop| is set to true; returns false |
| 62 // when any failure occurs during the watch, including |message_pipe_| is |
| 63 // closed. |
| 64 virtual bool SyncWatch(const bool* should_stop) = 0; |
| 65 }; |
| 66 |
| 42 // MultiplexRouter supports routing messages for multiple interfaces over a | 67 // MultiplexRouter supports routing messages for multiple interfaces over a |
| 43 // single message pipe. | 68 // single message pipe. |
| 44 // | 69 // |
| 45 // It is created on the thread where the master interface of the message pipe | 70 // It is created on the thread where the master interface of the message pipe |
| 46 // lives. Although it is ref-counted, it is guarateed to be destructed on the | 71 // lives. Although it is ref-counted, it is guarateed to be destructed on the |
| 47 // same thread. | 72 // same thread. |
| 48 // Some public methods are only allowed to be called on the creating thread; | 73 // Some public methods are only allowed to be called on the creating thread; |
| 49 // while the others are safe to call from any threads. Please see the method | 74 // while the others are safe to call from any threads. Please see the method |
| 50 // comments for more details. | 75 // comments for more details. |
| 51 class MultiplexRouter | 76 class MultiplexRouter |
| (...skipping 19 matching lines...) Expand all Loading... |
| 71 // is used locally. | 96 // is used locally. |
| 72 // Typically, this method is used to (1) create an endpoint handle for the | 97 // Typically, this method is used to (1) create an endpoint handle for the |
| 73 // master interface; or (2) create an endpoint handle on receiving an | 98 // master interface; or (2) create an endpoint handle on receiving an |
| 74 // interface ID from the message pipe. | 99 // interface ID from the message pipe. |
| 75 ScopedInterfaceEndpointHandle CreateLocalEndpointHandle(InterfaceId id); | 100 ScopedInterfaceEndpointHandle CreateLocalEndpointHandle(InterfaceId id); |
| 76 | 101 |
| 77 // Closes an interface endpoint handle. | 102 // Closes an interface endpoint handle. |
| 78 void CloseEndpointHandle(InterfaceId id, bool is_local); | 103 void CloseEndpointHandle(InterfaceId id, bool is_local); |
| 79 | 104 |
| 80 // Attaches an client to the specified endpoint to send and receive messages. | 105 // Attaches an client to the specified endpoint to send and receive messages. |
| 81 void AttachEndpointClient(const ScopedInterfaceEndpointHandle& handle, | 106 // The returned object is owned by the router. It should only be used on the |
| 82 InterfaceEndpointClient* endpoint_client); | 107 // same thread as this call, and only before the client is detached using |
| 108 // DetachEndpointClient(). |
| 109 InterfaceEndpointController* AttachEndpointClient( |
| 110 const ScopedInterfaceEndpointHandle& handle, |
| 111 InterfaceEndpointClient* endpoint_client); |
| 112 |
| 83 // Detaches the client attached to the specified endpoint. It should be called | 113 // Detaches the client attached to the specified endpoint. It should be called |
| 84 // on the same thread as the corresponding AttachEndpointClient() call. | 114 // on the same thread as the corresponding AttachEndpointClient() call. |
| 85 void DetachEndpointClient(const ScopedInterfaceEndpointHandle& handle); | 115 void DetachEndpointClient(const ScopedInterfaceEndpointHandle& handle); |
| 86 | 116 |
| 87 bool SendMessage(const ScopedInterfaceEndpointHandle& handle, | |
| 88 Message* message); | |
| 89 | |
| 90 // Raises an error on the underlying message pipe. It disconnects the pipe | 117 // Raises an error on the underlying message pipe. It disconnects the pipe |
| 91 // and notifies all interfaces running on this pipe. | 118 // and notifies all interfaces running on this pipe. |
| 92 void RaiseError(); | 119 void RaiseError(); |
| 93 | 120 |
| 94 scoped_ptr<AssociatedGroup> CreateAssociatedGroup(); | 121 scoped_ptr<AssociatedGroup> CreateAssociatedGroup(); |
| 95 | 122 |
| 96 static MultiplexRouter* GetRouter(AssociatedGroup* associated_group); | 123 static MultiplexRouter* GetRouter(AssociatedGroup* associated_group); |
| 97 | 124 |
| 98 // --------------------------------------------------------------------------- | 125 // --------------------------------------------------------------------------- |
| 99 // The following public methods are called on the creating thread. | 126 // The following public methods are called on the creating thread. |
| 100 | 127 |
| 101 // Please note that this method shouldn't be called unless it results from an | 128 // Please note that this method shouldn't be called unless it results from an |
| 102 // explicit request of the user of bindings (e.g., the user sets an | 129 // explicit request of the user of bindings (e.g., the user sets an |
| 103 // InterfacePtr to null or closes a Binding). | 130 // InterfacePtr to null or closes a Binding). |
| 104 void CloseMessagePipe() { | 131 void CloseMessagePipe() { |
| 105 DCHECK(thread_checker_.CalledOnValidThread()); | 132 DCHECK(thread_checker_.CalledOnValidThread()); |
| 106 connector_.CloseMessagePipe(); | 133 connector_.CloseMessagePipe(); |
| 134 // CloseMessagePipe() above won't trigger connection error handler. |
| 135 // Explicitly call OnPipeConnectionError() so that associated endpoints will |
| 136 // get notified. |
| 137 OnPipeConnectionError(); |
| 107 } | 138 } |
| 108 | 139 |
| 109 // Extracts the underlying message pipe. | 140 // Extracts the underlying message pipe. |
| 110 ScopedMessagePipeHandle PassMessagePipe() { | 141 ScopedMessagePipeHandle PassMessagePipe() { |
| 111 DCHECK(thread_checker_.CalledOnValidThread()); | 142 DCHECK(thread_checker_.CalledOnValidThread()); |
| 112 DCHECK(!HasAssociatedEndpoints()); | 143 DCHECK(!HasAssociatedEndpoints()); |
| 113 return connector_.PassMessagePipe(); | 144 return connector_.PassMessagePipe(); |
| 114 } | 145 } |
| 115 | 146 |
| 116 // Blocks the current thread until the first incoming message, or |deadline|. | 147 // Blocks the current thread until the first incoming message, or |deadline|. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 | 191 |
| 161 // MessageReceiver implementation: | 192 // MessageReceiver implementation: |
| 162 bool Accept(Message* message) override; | 193 bool Accept(Message* message) override; |
| 163 | 194 |
| 164 // PipeControlMessageHandlerDelegate implementation: | 195 // PipeControlMessageHandlerDelegate implementation: |
| 165 bool OnPeerAssociatedEndpointClosed(InterfaceId id) override; | 196 bool OnPeerAssociatedEndpointClosed(InterfaceId id) override; |
| 166 bool OnAssociatedEndpointClosedBeforeSent(InterfaceId id) override; | 197 bool OnAssociatedEndpointClosedBeforeSent(InterfaceId id) override; |
| 167 | 198 |
| 168 void OnPipeConnectionError(); | 199 void OnPipeConnectionError(); |
| 169 | 200 |
| 201 // Specifies whether we are allowed to directly call into |
| 202 // InterfaceEndpointClient (given that we are already on the same thread as |
| 203 // the client). |
| 204 enum ClientCallBehavior { |
| 205 // Don't call any InterfaceEndpointClient methods directly. |
| 206 NO_DIRECT_CLIENT_CALLS, |
| 207 // Only call InterfaceEndpointClient::HandleIncomingMessage directly to |
| 208 // handle sync messages. |
| 209 ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES, |
| 210 // Allow to call any InterfaceEndpointClient methods directly. |
| 211 ALLOW_DIRECT_CLIENT_CALLS |
| 212 }; |
| 213 |
| 170 // Processes enqueued tasks (incoming messages and error notifications). | 214 // Processes enqueued tasks (incoming messages and error notifications). |
| 171 // If |force_async| is true, it guarantees not to call any | |
| 172 // InterfaceEndpointClient methods directly. | |
| 173 // | 215 // |
| 174 // Note: Because calling into InterfaceEndpointClient may lead to destruction | 216 // Note: Because calling into InterfaceEndpointClient may lead to destruction |
| 175 // of this object, if |force_async| is set to false, the caller needs to hold | 217 // of this object, if direct calls are allowed, the caller needs to hold on to |
| 176 // on to a ref outside of |lock_| before calling this method. | 218 // a ref outside of |lock_| before calling this method. |
| 177 void ProcessTasks(bool force_async); | 219 void ProcessTasks(ClientCallBehavior client_call_behavior); |
| 220 |
| 221 // Returns whether there are more in the queue. |
| 222 bool ProcessFirstSyncMessageForEndpoint(InterfaceId id); |
| 178 | 223 |
| 179 // Returns true to indicate that |task|/|message| has been processed. | 224 // Returns true to indicate that |task|/|message| has been processed. |
| 180 bool ProcessNotifyErrorTask(Task* task, bool force_async); | 225 bool ProcessNotifyErrorTask(Task* task, |
| 181 bool ProcessIncomingMessage(Message* message, bool force_async); | 226 ClientCallBehavior client_call_behavior); |
| 227 bool ProcessIncomingMessage(Message* message, |
| 228 ClientCallBehavior client_call_behavior); |
| 182 | 229 |
| 183 void MaybePostToProcessTasks(base::SingleThreadTaskRunner* task_runner); | 230 void MaybePostToProcessTasks(base::SingleThreadTaskRunner* task_runner); |
| 184 void LockAndCallProcessTasks(); | 231 void LockAndCallProcessTasks(); |
| 185 | 232 |
| 186 // Updates the state of |endpoint|. If both the endpoint and its peer have | 233 // Updates the state of |endpoint|. If both the endpoint and its peer have |
| 187 // been closed, removes it from |endpoints_|. | 234 // been closed, removes it from |endpoints_|. |
| 188 // NOTE: The method may invalidate |endpoint|. | 235 // NOTE: The method may invalidate |endpoint|. |
| 189 enum EndpointStateUpdateType { ENDPOINT_CLOSED, PEER_ENDPOINT_CLOSED }; | 236 enum EndpointStateUpdateType { ENDPOINT_CLOSED, PEER_ENDPOINT_CLOSED }; |
| 190 void UpdateEndpointStateMayRemove(InterfaceEndpoint* endpoint, | 237 void UpdateEndpointStateMayRemove(InterfaceEndpoint* endpoint, |
| 191 EndpointStateUpdateType type); | 238 EndpointStateUpdateType type); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 206 | 253 |
| 207 // Protects the following members. | 254 // Protects the following members. |
| 208 mutable base::Lock lock_; | 255 mutable base::Lock lock_; |
| 209 PipeControlMessageHandler control_message_handler_; | 256 PipeControlMessageHandler control_message_handler_; |
| 210 PipeControlMessageProxy control_message_proxy_; | 257 PipeControlMessageProxy control_message_proxy_; |
| 211 | 258 |
| 212 std::map<InterfaceId, scoped_refptr<InterfaceEndpoint>> endpoints_; | 259 std::map<InterfaceId, scoped_refptr<InterfaceEndpoint>> endpoints_; |
| 213 uint32_t next_interface_id_value_; | 260 uint32_t next_interface_id_value_; |
| 214 | 261 |
| 215 std::deque<scoped_ptr<Task>> tasks_; | 262 std::deque<scoped_ptr<Task>> tasks_; |
| 263 // It refers to tasks in |tasks_| and doesn't own any of them. |
| 264 std::map<InterfaceId, std::deque<Task*>> sync_message_tasks_; |
| 216 | 265 |
| 217 bool posted_to_process_tasks_; | 266 bool posted_to_process_tasks_; |
| 218 | 267 |
| 219 bool testing_mode_; | 268 bool testing_mode_; |
| 220 | 269 |
| 221 DISALLOW_COPY_AND_ASSIGN(MultiplexRouter); | 270 DISALLOW_COPY_AND_ASSIGN(MultiplexRouter); |
| 222 }; | 271 }; |
| 223 | 272 |
| 224 } // namespace internal | 273 } // namespace internal |
| 225 } // namespace mojo | 274 } // namespace mojo |
| 226 | 275 |
| 227 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_ | 276 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_ |
| OLD | NEW |