Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: mojo/public/cpp/shell/service.h

Issue 287143003: Mojo: Internalize ServiceConnector<> (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add missing function Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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_SHELL_SERVICE_H_
6 #define MOJO_PUBLIC_SHELL_SERVICE_H_
7
8 #include <assert.h>
9
10 #include <vector>
11
12 #include "mojo/public/cpp/bindings/allocation_scope.h"
13 #include "mojo/public/interfaces/shell/shell.mojom.h"
14
15 // Utility classes for creating ShellClients that vend service instances.
16 // To use define a class that implements your specific server api, e.g. FooImpl
17 // to implement a service named Foo. That class must define an empty constructor
18 // and the Initialize() method.
19 // class FooImpl : public Foo {
20 // public:
21 // FooImpl();
22 // void Initialize();
23 // private:
24 // ServiceConnector<FooImpl>* service_connector_;
25 // };
26 //
27 //
28 // To simplify further FooImpl can use the ServiceConnection<> template.
29 // class FooImpl : public ServiceConnection<Foo, FooImpl> {
30 // public:
31 // FooImpl();
32 // ...
33 // <Foo implementation>
34 // };
35 //
36 // Instances of FooImpl will be created by a specialized ServiceConnector
37 //
38 // ServiceConnector<FooImpl>
39 //
40 // Optionally the classes can be specializeed with a shared context
41 // class ServiceConnector<FooImpl, MyContext>
42 // and
43 // class FooImpl : public ServiceConnection<Foo, FooImpl, MyContext>
44 //
45 // foo_connector = new ServiceConnector<FooImpl, MyContext>(my_context);
46 // instances of FooImpl can call context() and retrieve the value of my_context.
47 //
48 // Lastly create an Application instance that collects all the
49 // ServiceConnectors.
50 //
51 // Application app(shell_handle);
52 // app.AddServiceConnector(new ServiceConnector<FooImpl>);
53 //
54 //
55 // Specialization of ServiceConnector.
56 // ServiceImpl: Implementation of Service interface.
57 // Context: Optional type of shared context.v
58 //
59 //
60 namespace mojo {
61
62 namespace internal {
63 class ServiceConnectorBase {
64 public:
65 class Owner : public ShellClient {
66 public:
67 Owner(ScopedMessagePipeHandle shell_handle);
68 virtual ~Owner();
69 Shell* shell() { return shell_.get(); }
70 virtual void AddServiceConnector(
71 internal::ServiceConnectorBase* service_connector) = 0;
72 virtual void RemoveServiceConnector(
73 internal::ServiceConnectorBase* service_connector) = 0;
74
75 protected:
76 void set_service_connector_owner(ServiceConnectorBase* service_connector,
77 Owner* owner) {
78 service_connector->owner_ = owner;
79 }
80 ShellPtr shell_;
81 };
82 ServiceConnectorBase() : owner_(NULL) {}
83 virtual ~ServiceConnectorBase();
84 Shell* shell() { return owner_->shell(); }
85 virtual void AcceptConnection(const std::string& url,
86 ScopedMessagePipeHandle client_handle) = 0;
87
88 protected:
89 Owner* owner_;
90 };
91 } // namespace internal
92
93 template <class ServiceImpl, typename Context=void>
94 class ServiceConnector : public internal::ServiceConnectorBase {
95 public:
96 ServiceConnector(Context* context = NULL) : context_(context) {}
97
98 virtual ~ServiceConnector() {
99 ConnectionList doomed;
100 doomed.swap(connections_);
101 for (typename ConnectionList::iterator it = doomed.begin();
102 it != doomed.end(); ++it) {
103 delete *it;
104 }
105 assert(connections_.empty()); // No one should have added more!
106 }
107
108 virtual void AcceptConnection(const std::string& url,
109 ScopedMessagePipeHandle handle) MOJO_OVERRIDE {
110 ServiceImpl* impl = BindToPipe(new ServiceImpl(), handle.Pass());
111 impl->set_connector(this);
112
113 connections_.push_back(impl);
114
115 impl->Initialize();
116 }
117
118 void RemoveConnection(ServiceImpl* impl) {
119 // Called from ~ServiceImpl, in response to a connection error.
120 for (typename ConnectionList::iterator it = connections_.begin();
121 it != connections_.end(); ++it) {
122 if (*it == impl) {
123 delete impl;
124 connections_.erase(it);
125 if (connections_.empty())
126 owner_->RemoveServiceConnector(this);
127 return;
128 }
129 }
130 }
131
132 Context* context() const { return context_; }
133
134 private:
135 typedef std::vector<ServiceImpl*> ConnectionList;
136 ConnectionList connections_;
137 Context* context_;
138 };
139
140 // Specialization of ServiceConnection.
141 // ServiceInterface: Service interface.
142 // ServiceImpl: Subclass of ServiceConnection<...>.
143 // Context: Optional type of shared context.
144 template <class ServiceInterface, class ServiceImpl, typename Context=void>
145 class ServiceConnection : public InterfaceImpl<ServiceInterface> {
146 protected:
147 // NOTE: shell() and context() are not available at construction time.
148 // Initialize() will be called once those are available.
149 ServiceConnection() : service_connector_(NULL) {}
150
151 virtual ~ServiceConnection() {}
152
153 virtual void OnConnectionError() MOJO_OVERRIDE {
154 service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this));
155 }
156
157 // Shadow this method in ServiceImpl to perform one-time initialization.
158 // At the time this is called, shell() and context() will be available.
159 // NOTE: No need to call the base class Initialize from your subclass. It
160 // will always be a no-op.
161 void Initialize() {}
162
163 Shell* shell() {
164 return service_connector_->shell();
165 }
166
167 Context* context() const {
168 return service_connector_->context();
169 }
170
171 private:
172 friend class ServiceConnector<ServiceImpl, Context>;
173
174 // Called shortly after this class is instantiated.
175 void set_connector(ServiceConnector<ServiceImpl, Context>* connector) {
176 service_connector_ = connector;
177 }
178
179 ServiceConnector<ServiceImpl, Context>* service_connector_;
180 };
181
182 template <typename Interface>
183 inline void ConnectTo(Shell* shell, const std::string& url,
184 InterfacePtr<Interface>* ptr) {
185 MessagePipe pipe;
186 ptr->Bind(pipe.handle0.Pass());
187
188 AllocationScope scope;
189 shell->Connect(url, pipe.handle1.Pass());
190 }
191
192 } // namespace mojo
193
194 #endif // MOJO_PUBLIC_SHELL_SERVICE_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/shell/lib/service_connector.cc ('k') | mojo/service_manager/service_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698