• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_INTERFACE_IMPL_INTERNAL_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_
7 
8 #include "mojo/public/cpp/bindings/error_handler.h"
9 #include "mojo/public/cpp/bindings/interface_ptr.h"
10 #include "mojo/public/cpp/bindings/lib/filter_chain.h"
11 #include "mojo/public/cpp/bindings/lib/message_header_validator.h"
12 #include "mojo/public/cpp/environment/environment.h"
13 #include "mojo/public/cpp/environment/logging.h"
14 #include "mojo/public/cpp/system/macros.h"
15 
16 namespace mojo {
17 namespace internal {
18 
19 template <typename Interface>
20 class InterfaceImplBase : public Interface {
21  public:
~InterfaceImplBase()22   virtual ~InterfaceImplBase() {}
23   virtual void OnConnectionEstablished() = 0;
24   virtual void OnConnectionError() = 0;
25 };
26 
27 template <typename Interface>
28 class InterfaceImplState : public ErrorHandler {
29  public:
30   typedef typename Interface::Client Client;
31 
InterfaceImplState(InterfaceImplBase<Interface> * instance)32   explicit InterfaceImplState(InterfaceImplBase<Interface>* instance)
33       : router_(NULL),
34         proxy_(NULL),
35         instance_bound_to_pipe_(false)
36 #ifndef NDEBUG
37         ,
38         deleting_instance_due_to_error_(false)
39 #endif
40   {
41     MOJO_DCHECK(instance);
42     stub_.set_sink(instance);
43   }
44 
~InterfaceImplState()45   virtual ~InterfaceImplState() {
46 #ifndef NDEBUG
47     MOJO_DCHECK(!instance_bound_to_pipe_ || deleting_instance_due_to_error_);
48 #endif
49     delete proxy_;
50     if (router_) {
51       router_->set_error_handler(NULL);
52       delete router_;
53     }
54   }
55 
56   void BindProxy(
57       InterfacePtr<Interface>* ptr,
58       bool instance_bound_to_pipe,
59       const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
60     MessagePipe pipe;
61     ptr->Bind(pipe.handle0.Pass(), waiter);
62     Bind(pipe.handle1.Pass(), instance_bound_to_pipe, waiter);
63   }
64 
Bind(ScopedMessagePipeHandle handle,bool instance_bound_to_pipe,const MojoAsyncWaiter * waiter)65   void Bind(ScopedMessagePipeHandle handle,
66             bool instance_bound_to_pipe,
67             const MojoAsyncWaiter* waiter) {
68     MOJO_CHECK(!router_);
69 
70     FilterChain filters;
71     filters.Append<MessageHeaderValidator>();
72     filters.Append<typename Interface::RequestValidator_>();
73     filters.Append<typename Interface::Client::ResponseValidator_>();
74 
75     router_ = new Router(handle.Pass(), filters.Pass(), waiter);
76     router_->set_incoming_receiver(&stub_);
77     router_->set_error_handler(this);
78 
79     proxy_ = new typename Client::Proxy_(router_);
80 
81     instance_bound_to_pipe_ = instance_bound_to_pipe;
82 
83     instance()->OnConnectionEstablished();
84   }
85 
WaitForIncomingMethodCall()86   bool WaitForIncomingMethodCall() {
87     MOJO_DCHECK(router_);
88     return router_->WaitForIncomingMessage();
89   }
90 
router()91   Router* router() { return router_; }
client()92   Client* client() { return proxy_; }
93 
94  private:
instance()95   InterfaceImplBase<Interface>* instance() {
96     return static_cast<InterfaceImplBase<Interface>*>(stub_.sink());
97   }
98 
OnConnectionError()99   virtual void OnConnectionError() MOJO_OVERRIDE {
100     // If the the instance is not bound to the pipe, the instance might choose
101     // to delete itself in the OnConnectionError handler, which would in turn
102     // delete this.  Save the error behavior before invoking the error handler
103     // so we can correctly decide what to do.
104     bool bound = instance_bound_to_pipe_;
105     instance()->OnConnectionError();
106     if (!bound)
107       return;
108 #ifndef NDEBUG
109     deleting_instance_due_to_error_ = true;
110 #endif
111     delete instance();
112   }
113 
114   Router* router_;
115   typename Client::Proxy_* proxy_;
116   typename Interface::Stub_ stub_;
117   bool instance_bound_to_pipe_;
118 #ifndef NDEBUG
119   bool deleting_instance_due_to_error_;
120 #endif
121 
122   MOJO_DISALLOW_COPY_AND_ASSIGN(InterfaceImplState);
123 };
124 
125 }  // namespace internal
126 }  // namespace mojo
127 
128 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_
129