1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2015 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h>
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <deque>
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <map>
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <memory>
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <string>
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/logging.h"
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/macros.h"
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/memory/ref_counted.h"
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/memory/weak_ptr.h"
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/single_thread_task_runner.h"
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/synchronization/lock.h"
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/threading/thread_checker.h"
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/associated_group_controller.h"
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/connector.h"
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/interface_id.h"
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/message_header_validator.h"
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/pipe_control_message_handler.h"
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h"
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/pipe_control_message_proxy.h"
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace base {
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass SingleThreadTaskRunner;
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass AssociatedGroup;
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace internal {
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// MultiplexRouter supports routing messages for multiple interfaces over a
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// single message pipe.
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez//
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// It is created on the thread where the master interface of the message pipe
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// lives. Although it is ref-counted, it is guarateed to be destructed on the
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// same thread.
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Some public methods are only allowed to be called on the creating thread;
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// while the others are safe to call from any threads. Please see the method
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// comments for more details.
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MultiplexRouter
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    : public MessageReceiver,
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      public AssociatedGroupController,
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      public PipeControlMessageHandlerDelegate {
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // If |set_interface_id_namespace_bit| is true, the interface IDs generated by
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // this router will have the highest bit set.
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MultiplexRouter(bool set_interface_id_namespace_bit,
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  ScopedMessagePipeHandle message_pipe,
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                  scoped_refptr<base::SingleThreadTaskRunner> runner);
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Sets the master interface name for this router. Only used when reporting
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // message header or control message validation errors.
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void SetMasterInterfaceName(const std::string& name);
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // ---------------------------------------------------------------------------
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // The following public methods are safe to call from any threads.
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // AssociatedGroupController implementation:
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void CreateEndpointHandlePair(
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      ScopedInterfaceEndpointHandle* local_endpoint,
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      ScopedInterfaceEndpointHandle* remote_endpoint) override;
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ScopedInterfaceEndpointHandle CreateLocalEndpointHandle(
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      InterfaceId id) override;
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void CloseEndpointHandle(InterfaceId id, bool is_local) override;
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  InterfaceEndpointController* AttachEndpointClient(
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      const ScopedInterfaceEndpointHandle& handle,
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      InterfaceEndpointClient* endpoint_client,
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      scoped_refptr<base::SingleThreadTaskRunner> runner) override;
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void DetachEndpointClient(
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      const ScopedInterfaceEndpointHandle& handle) override;
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void RaiseError() override;
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // ---------------------------------------------------------------------------
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // The following public methods are called on the creating thread.
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Please note that this method shouldn't be called unless it results from an
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // explicit request of the user of bindings (e.g., the user sets an
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // InterfacePtr to null or closes a Binding).
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void CloseMessagePipe();
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Extracts the underlying message pipe.
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ScopedMessagePipeHandle PassMessagePipe() {
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(thread_checker_.CalledOnValidThread());
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(!HasAssociatedEndpoints());
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return connector_.PassMessagePipe();
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Blocks the current thread until the first incoming message, or |deadline|.
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool WaitForIncomingMessage(MojoDeadline deadline) {
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(thread_checker_.CalledOnValidThread());
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return connector_.WaitForIncomingMessage(deadline);
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // See Binding for details of pause/resume.
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void PauseIncomingMethodCallProcessing() {
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(thread_checker_.CalledOnValidThread());
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    connector_.PauseIncomingMethodCallProcessing();
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void ResumeIncomingMethodCallProcessing() {
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(thread_checker_.CalledOnValidThread());
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    connector_.ResumeIncomingMethodCallProcessing();
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Whether there are any associated interfaces running currently.
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool HasAssociatedEndpoints() const;
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Sets this object to testing mode.
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // In testing mode, the object doesn't disconnect the underlying message pipe
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // when it receives unexpected or invalid messages.
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void EnableTestingMode();
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Is the router bound to a message pipe handle?
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool is_valid() const {
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(thread_checker_.CalledOnValidThread());
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return connector_.is_valid();
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // TODO(yzshen): consider removing this getter.
129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MessagePipeHandle handle() const {
130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(thread_checker_.CalledOnValidThread());
131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return connector_.handle();
132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private:
135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  class InterfaceEndpoint;
136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  struct Task;
137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ~MultiplexRouter() override;
139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // MessageReceiver implementation:
141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool Accept(Message* message) override;
142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // PipeControlMessageHandlerDelegate implementation:
144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool OnPeerAssociatedEndpointClosed(InterfaceId id) override;
145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool OnAssociatedEndpointClosedBeforeSent(InterfaceId id) override;
146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void OnPipeConnectionError();
148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Specifies whether we are allowed to directly call into
150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // InterfaceEndpointClient (given that we are already on the same thread as
151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // the client).
152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  enum ClientCallBehavior {
153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Don't call any InterfaceEndpointClient methods directly.
154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    NO_DIRECT_CLIENT_CALLS,
155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Only call InterfaceEndpointClient::HandleIncomingMessage directly to
156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // handle sync messages.
157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES,
158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // Allow to call any InterfaceEndpointClient methods directly.
159645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ALLOW_DIRECT_CLIENT_CALLS
160645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  };
161645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
162645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Processes enqueued tasks (incoming messages and error notifications).
163645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |current_task_runner| is only used when |client_call_behavior| is
164645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // ALLOW_DIRECT_CLIENT_CALLS to determine whether we are on the right task
165645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // runner to make client calls for async messages or connection error
166645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // notifications.
167645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  //
168645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Note: Because calling into InterfaceEndpointClient may lead to destruction
169645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // of this object, if direct calls are allowed, the caller needs to hold on to
170645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // a ref outside of |lock_| before calling this method.
171645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void ProcessTasks(ClientCallBehavior client_call_behavior,
172645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                    base::SingleThreadTaskRunner* current_task_runner);
173645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
174645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Processes the first queued sync message for the endpoint corresponding to
175645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // |id|; returns whether there are more sync messages for that endpoint in the
176645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // queue.
177645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  //
178645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // This method is only used by enpoints during sync watching. Therefore, not
179645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // all sync messages are handled by it.
180645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool ProcessFirstSyncMessageForEndpoint(InterfaceId id);
181645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
182645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Returns true to indicate that |task|/|message| has been processed.
183645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool ProcessNotifyErrorTask(
184645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      Task* task,
185645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      ClientCallBehavior client_call_behavior,
186645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      base::SingleThreadTaskRunner* current_task_runner);
187645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool ProcessIncomingMessage(
188645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      Message* message,
189645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      ClientCallBehavior client_call_behavior,
190645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      base::SingleThreadTaskRunner* current_task_runner);
191645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
192645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void MaybePostToProcessTasks(base::SingleThreadTaskRunner* task_runner);
193645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void LockAndCallProcessTasks();
194645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
195645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Updates the state of |endpoint|. If both the endpoint and its peer have
196645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // been closed, removes it from |endpoints_|.
197645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // NOTE: The method may invalidate |endpoint|.
198645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  enum EndpointStateUpdateType { ENDPOINT_CLOSED, PEER_ENDPOINT_CLOSED };
199645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void UpdateEndpointStateMayRemove(InterfaceEndpoint* endpoint,
200645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                    EndpointStateUpdateType type);
201645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
202645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void RaiseErrorInNonTestingMode();
203645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
204645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  InterfaceEndpoint* FindOrInsertEndpoint(InterfaceId id, bool* inserted);
205645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
206645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Whether to set the namespace bit when generating interface IDs. Please see
207645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // comments of kInterfaceIdNamespaceMask.
208645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const bool set_interface_id_namespace_bit_;
209645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
210645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MessageHeaderValidator header_validator_;
211645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  Connector connector_;
212645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
213645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  base::ThreadChecker thread_checker_;
214645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
215645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Protects the following members.
216645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  mutable base::Lock lock_;
217645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PipeControlMessageHandler control_message_handler_;
218645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  PipeControlMessageProxy control_message_proxy_;
219645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
220645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::map<InterfaceId, scoped_refptr<InterfaceEndpoint>> endpoints_;
221645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t next_interface_id_value_;
222645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
223645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::deque<std::unique_ptr<Task>> tasks_;
224645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // It refers to tasks in |tasks_| and doesn't own any of them.
225645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::map<InterfaceId, std::deque<Task*>> sync_message_tasks_;
226645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
227645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool posted_to_process_tasks_;
228645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  scoped_refptr<base::SingleThreadTaskRunner> posted_to_task_runner_;
229645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
230645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool encountered_error_;
231645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
232645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool testing_mode_;
233645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
234645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DISALLOW_COPY_AND_ASSIGN(MultiplexRouter);
235645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
236645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
237645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace internal
238645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
239645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
240645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_
241