1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ROUTER_H_
6#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ROUTER_H_
7
8#include <map>
9
10#include "mojo/public/cpp/bindings/lib/connector.h"
11#include "mojo/public/cpp/bindings/lib/filter_chain.h"
12#include "mojo/public/cpp/bindings/lib/shared_data.h"
13#include "mojo/public/cpp/environment/environment.h"
14
15namespace mojo {
16namespace internal {
17
18class Router : public MessageReceiverWithResponder {
19 public:
20  Router(ScopedMessagePipeHandle message_pipe,
21         FilterChain filters,
22         const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter());
23  virtual ~Router();
24
25  // Sets the receiver to handle messages read from the message pipe that do
26  // not have the kMessageIsResponse flag set.
27  void set_incoming_receiver(MessageReceiverWithResponder* receiver) {
28    incoming_receiver_ = receiver;
29  }
30
31  // Sets the error handler to receive notifications when an error is
32  // encountered while reading from the pipe or waiting to read from the pipe.
33  void set_error_handler(ErrorHandler* error_handler) {
34    connector_.set_error_handler(error_handler);
35  }
36
37  // Returns true if an error was encountered while reading from the pipe or
38  // waiting to read from the pipe.
39  bool encountered_error() const { return connector_.encountered_error(); }
40
41  void CloseMessagePipe() {
42    connector_.CloseMessagePipe();
43  }
44
45  ScopedMessagePipeHandle PassMessagePipe() {
46    return connector_.PassMessagePipe();
47  }
48
49  // MessageReceiver implementation:
50  virtual bool Accept(Message* message) MOJO_OVERRIDE;
51  virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
52      MOJO_OVERRIDE;
53
54  // Blocks the current thread for the first incoming method call, i.e., either
55  // a call to a client method or a callback method.
56  bool WaitForIncomingMessage() {
57    return connector_.WaitForIncomingMessage();
58  }
59
60  // Sets this object to testing mode.
61  // In testing mode:
62  // - the object is more tolerant of unrecognized response messages;
63  // - the connector continues working after seeing errors from its incoming
64  //   receiver.
65  void EnableTestingMode();
66
67 private:
68  typedef std::map<uint64_t, MessageReceiver*> ResponderMap;
69
70  class HandleIncomingMessageThunk : public MessageReceiver {
71   public:
72    HandleIncomingMessageThunk(Router* router);
73    virtual ~HandleIncomingMessageThunk();
74
75    // MessageReceiver implementation:
76    virtual bool Accept(Message* message) MOJO_OVERRIDE;
77
78   private:
79    Router* router_;
80  };
81
82  bool HandleIncomingMessage(Message* message);
83
84  HandleIncomingMessageThunk thunk_;
85  FilterChain filters_;
86  Connector connector_;
87  SharedData<Router*> weak_self_;
88  MessageReceiverWithResponder* incoming_receiver_;
89  ResponderMap responders_;
90  uint64_t next_request_id_;
91  bool testing_mode_;
92};
93
94}  // namespace internal
95}  // namespace mojo
96
97#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_ROUTER_H_
98