| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 #include <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "examples/echo/echo.mojom.h" | 7 #include "examples/echo/echo.mojom.h" |
| 8 #include "mojo/common/binding_set.h" | 8 #include "mojo/common/binding_set.h" |
| 9 #include "mojo/public/c/system/main.h" | 9 #include "mojo/public/c/system/main.h" |
| 10 #include "mojo/public/cpp/application/application_connection.h" | 10 #include "mojo/public/cpp/application/application_connection.h" |
| 11 #include "mojo/public/cpp/application/application_delegate.h" | 11 #include "mojo/public/cpp/application/application_delegate.h" |
| 12 #include "mojo/public/cpp/application/application_runner.h" | 12 #include "mojo/public/cpp/application/application_runner.h" |
| 13 #include "mojo/public/cpp/application/interface_factory.h" | |
| 14 #include "mojo/public/cpp/bindings/strong_binding.h" | 13 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 15 | 14 |
| 16 namespace mojo { | 15 namespace mojo { |
| 17 namespace examples { | 16 namespace examples { |
| 18 | 17 |
| 19 // This file demonstrates three ways to implement a simple Mojo server. Because | 18 // This file demonstrates three ways to implement a simple Mojo server. Because |
| 20 // there's no state that's saved per-pipe, all three servers appear to the | 19 // there's no state that's saved per-pipe, all three servers appear to the |
| 21 // client to do exactly the same thing. | 20 // client to do exactly the same thing. |
| 22 // | 21 // |
| 23 // To choose one of the them, update MojoMain() at the end of this file. | 22 // To choose one of the them, update MojoMain() at the end of this file. |
| 24 // 1. MultiServer - creates a new object for each connection. Cleans up by using | 23 // 1. MultiServer - creates a new object for each connection. Cleans up by using |
| 25 // StrongBinding. | 24 // StrongBinding. |
| 26 // 2. SingletonServer -- all requests are handled by one object. Connections are | 25 // 2. SingletonServer -- all requests are handled by one object. Connections are |
| 27 // tracked using BindingSet. | 26 // tracked using BindingSet. |
| 28 // 3. OneAtATimeServer -- each Create call from InterfaceFactory<> closes the | 27 // 3. OneAtATimeServer -- each request "replaces" any previous request. Any old |
| 29 // old interface pipe and binds the new interface pipe. | 28 // interface pipe is closed and the new interface pipe is bound. |
| 30 | 29 |
| 31 // EchoImpl defines our implementation of the Echo interface. | 30 // EchoImpl defines our implementation of the Echo interface. |
| 32 // It is used by all three server variants. | 31 // It is used by all three server variants. |
| 33 class EchoImpl : public Echo { | 32 class EchoImpl : public Echo { |
| 34 public: | 33 public: |
| 35 void EchoString(const mojo::String& value, | 34 void EchoString(const mojo::String& value, |
| 36 const Callback<void(mojo::String)>& callback) override { | 35 const Callback<void(mojo::String)>& callback) override { |
| 37 callback.Run(value); | 36 callback.Run(value); |
| 38 } | 37 } |
| 39 }; | 38 }; |
| 40 | 39 |
| 41 // StrongBindingEchoImpl inherits from EchoImpl and adds the StrongBinding<> | 40 // StrongBindingEchoImpl inherits from EchoImpl and adds the StrongBinding<> |
| 42 // class so instances will delete themselves when the message pipe is closed. | 41 // class so instances will delete themselves when the message pipe is closed. |
| 43 // This simplifies lifetime management. This class is only used by MultiServer. | 42 // This simplifies lifetime management. This class is only used by MultiServer. |
| 44 class StrongBindingEchoImpl : public EchoImpl { | 43 class StrongBindingEchoImpl : public EchoImpl { |
| 45 public: | 44 public: |
| 46 explicit StrongBindingEchoImpl(InterfaceRequest<Echo> handle) | 45 explicit StrongBindingEchoImpl(InterfaceRequest<Echo> handle) |
| 47 : strong_binding_(this, handle.Pass()) {} | 46 : strong_binding_(this, handle.Pass()) {} |
| 48 | 47 |
| 49 private: | 48 private: |
| 50 mojo::StrongBinding<Echo> strong_binding_; | 49 mojo::StrongBinding<Echo> strong_binding_; |
| 51 }; | 50 }; |
| 52 | 51 |
| 53 // MultiServer creates a new object to handle each message pipe. | 52 // MultiServer creates a new object to handle each message pipe. |
| 54 class MultiServer : public mojo::ApplicationDelegate, | 53 class MultiServer : public mojo::ApplicationDelegate { |
| 55 public mojo::InterfaceFactory<Echo> { | |
| 56 public: | 54 public: |
| 57 MultiServer() {} | 55 MultiServer() {} |
| 58 | 56 |
| 59 // From ApplicationDelegate | 57 // From ApplicationDelegate |
| 60 bool ConfigureIncomingConnection( | 58 bool ConfigureIncomingConnection( |
| 61 mojo::ApplicationConnection* connection) override { | 59 mojo::ApplicationConnection* connection) override { |
| 62 connection->AddService<Echo>(this); | 60 connection->GetServiceProviderImpl().AddService<Echo>( |
| 61 [](const mojo::ConnectionContext& connection_context, |
| 62 mojo::InterfaceRequest<Echo> echo_request) { |
| 63 // This object will be deleted automatically because of the use of |
| 64 // StrongBinding<> for the declaration of |strong_binding_|. |
| 65 new StrongBindingEchoImpl(echo_request.Pass()); |
| 66 }); |
| 63 return true; | 67 return true; |
| 64 } | 68 } |
| 65 | |
| 66 // From InterfaceFactory<Echo> | |
| 67 void Create(const mojo::ConnectionContext& connection_context, | |
| 68 mojo::InterfaceRequest<Echo> request) override { | |
| 69 // This object will be deleted automatically because of the use of | |
| 70 // StrongBinding<> for the declaration of |strong_binding_|. | |
| 71 new StrongBindingEchoImpl(request.Pass()); | |
| 72 } | |
| 73 }; | 69 }; |
| 74 | 70 |
| 75 // SingletonServer uses the same object to handle all message pipes. Useful | 71 // SingletonServer uses the same object to handle all message pipes. Useful |
| 76 // for stateless operation. | 72 // for stateless operation. |
| 77 class SingletonServer : public mojo::ApplicationDelegate, | 73 class SingletonServer : public mojo::ApplicationDelegate { |
| 78 public mojo::InterfaceFactory<Echo> { | |
| 79 public: | 74 public: |
| 80 SingletonServer() {} | 75 SingletonServer() {} |
| 81 | 76 |
| 82 // From ApplicationDelegate | 77 // From ApplicationDelegate |
| 83 bool ConfigureIncomingConnection( | 78 bool ConfigureIncomingConnection( |
| 84 mojo::ApplicationConnection* connection) override { | 79 mojo::ApplicationConnection* connection) override { |
| 85 connection->AddService<Echo>(this); | 80 connection->GetServiceProviderImpl().AddService<Echo>( |
| 81 [this](const mojo::ConnectionContext& connection_context, |
| 82 mojo::InterfaceRequest<Echo> echo_request) { |
| 83 // All channels will connect to this singleton object, so just |
| 84 // add the binding to our collection. |
| 85 bindings_.AddBinding(&echo_impl_, echo_request.Pass()); |
| 86 }); |
| 86 return true; | 87 return true; |
| 87 } | 88 } |
| 88 | 89 |
| 89 // From InterfaceFactory<Echo> | |
| 90 void Create(const mojo::ConnectionContext& connection_context, | |
| 91 mojo::InterfaceRequest<Echo> request) override { | |
| 92 // All channels will connect to this singleton object, so just | |
| 93 // add the binding to our collection. | |
| 94 bindings_.AddBinding(&echo_impl_, request.Pass()); | |
| 95 } | |
| 96 | |
| 97 private: | 90 private: |
| 98 EchoImpl echo_impl_; | 91 EchoImpl echo_impl_; |
| 99 | 92 |
| 100 mojo::BindingSet<Echo> bindings_; | 93 mojo::BindingSet<Echo> bindings_; |
| 101 }; | 94 }; |
| 102 | 95 |
| 103 // OneAtATimeServer works with only one pipe at a time. When a new pipe tries | 96 // OneAtATimeServer works with only one pipe at a time. When a new pipe tries |
| 104 // to bind, the previous pipe is closed. This would seem to be useful when | 97 // to bind, the previous pipe is closed. This would seem to be useful when |
| 105 // clients are expected to make a single call and then go away, but in fact it's | 98 // clients are expected to make a single call and then go away, but in fact it's |
| 106 // not reliable. There's a race condition because a second client could bind | 99 // not reliable. There's a race condition because a second client could bind |
| 107 // to the server before the first client called EchoString(). Therefore, this | 100 // to the server before the first client called EchoString(). Therefore, this |
| 108 // is an example of how not to write your code. | 101 // is an example of how not to write your code. |
| 109 class OneAtATimeServer : public mojo::ApplicationDelegate, | 102 class OneAtATimeServer : public mojo::ApplicationDelegate { |
| 110 public mojo::InterfaceFactory<Echo> { | |
| 111 public: | 103 public: |
| 112 OneAtATimeServer() : binding_(&echo_impl_) {} | 104 OneAtATimeServer() : binding_(&echo_impl_) {} |
| 113 | 105 |
| 114 // From ApplicationDelegate | 106 // From ApplicationDelegate |
| 115 bool ConfigureIncomingConnection( | 107 bool ConfigureIncomingConnection( |
| 116 mojo::ApplicationConnection* connection) override { | 108 mojo::ApplicationConnection* connection) override { |
| 117 connection->AddService<Echo>(this); | 109 connection->GetServiceProviderImpl().AddService<Echo>( |
| 110 [this](const mojo::ConnectionContext& connection_context, |
| 111 mojo::InterfaceRequest<Echo> echo_request) { |
| 112 binding_.Bind(echo_request.Pass()); |
| 113 }); |
| 118 return true; | 114 return true; |
| 119 } | 115 } |
| 120 | 116 |
| 121 // From InterfaceFactory<Echo> | |
| 122 void Create(const mojo::ConnectionContext& connection_context, | |
| 123 mojo::InterfaceRequest<Echo> request) override { | |
| 124 binding_.Bind(request.Pass()); | |
| 125 } | |
| 126 | |
| 127 private: | 117 private: |
| 128 EchoImpl echo_impl_; | 118 EchoImpl echo_impl_; |
| 129 | 119 |
| 130 mojo::Binding<Echo> binding_; | 120 mojo::Binding<Echo> binding_; |
| 131 }; | 121 }; |
| 132 | 122 |
| 133 } // namespace examples | 123 } // namespace examples |
| 134 } // namespace mojo | 124 } // namespace mojo |
| 135 | 125 |
| 136 MojoResult MojoMain(MojoHandle application_request) { | 126 MojoResult MojoMain(MojoHandle application_request) { |
| 137 // Uncomment one of the three servers at a time to see it work: | 127 // Uncomment one of the three servers at a time to see it work: |
| 138 mojo::ApplicationRunner runner(std::unique_ptr<mojo::examples::MultiServer>( | 128 mojo::ApplicationRunner runner(std::unique_ptr<mojo::examples::MultiServer>( |
| 139 new mojo::examples::MultiServer())); | 129 new mojo::examples::MultiServer())); |
| 140 // mojo::ApplicationRunner runner(new mojo::examples::SingletonServer()); | 130 // mojo::ApplicationRunner runner(new mojo::examples::SingletonServer()); |
| 141 // mojo::ApplicationRunner runner(new mojo::examples::OneAtATimeServer()); | 131 // mojo::ApplicationRunner runner(new mojo::examples::OneAtATimeServer()); |
| 142 | 132 |
| 143 return runner.Run(application_request); | 133 return runner.Run(application_request); |
| 144 } | 134 } |
| OLD | NEW |