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

Side by Side Diff: examples/indirect_service/indirect_service_demo.cc

Issue 733563002: Mojo Example that demos the difference between providing and requesting an interface (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Fixed Android build Created 6 years, 1 month 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
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 #include <cstdlib>
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/threading/thread.h"
10 #include "base/time/time.h"
11 #include "examples/indirect_service/indirect_service_demo.mojom.h"
12 #include "mojo/application/application_runner_chromium.h"
13 #include "mojo/common/message_pump_mojo.h"
14 #include "mojo/public/c/system/main.h"
15 #include "mojo/public/cpp/application/application_delegate.h"
16 #include "mojo/public/cpp/application/application_impl.h"
17
18 namespace mojo {
19 namespace examples {
20
21 class DemoTask;
22
23 typedef typename base::Callback<void(DemoTask*, const std::vector<int32_t>&)>
24 DemoTaskFinishedCallback;
25
26 // A thread that connects to the IndirectIntegerService, gets a connection
27 // to its IntegerService, and then calls Increment() iteration_count times.
28 // The results are saved and returned with the finished_callback.
29 class DemoTask {
30 public:
31 DemoTask(ScopedMessagePipeHandle proxy_handle,
32 const DemoTaskFinishedCallback& finished_callback,
33 unsigned iteration_count)
34 : proxy_handle_(proxy_handle.Pass()),
35 thread_("DemoTask"),
36 finished_callback_(finished_callback),
37 iteration_count_(iteration_count) {
38
39 base::Thread::Options options;
40 options.message_loop_type = base::MessageLoop::TYPE_CUSTOM;
41 options.message_pump_factory = base::Bind(&common::MessagePumpMojo::Create);
42 CHECK(thread_.StartWithOptions(options));
43
44 thread_.message_loop()->PostTask(
45 FROM_HERE, base::Bind(&DemoTask::Run, base::Unretained(this)));
46 }
47
48 void Run() {
49 integer_service_.Bind(proxy_handle_.Pass());
50 base::Callback<void(int32_t)> callback =
51 base::Bind(&DemoTask::SaveResultAndFinish, base::Unretained(this));
52 for(int unsigned i = 0; i < iteration_count_; i++) {
53 integer_service_->Increment(callback);
54 // To ensure that the DemoTask threads' execution overlaps, sleep.
55 if (i < iteration_count_ - 1)
56 base::PlatformThread::Sleep(
57 base::TimeDelta::FromMilliseconds(rand() % 10));
58 }
59 }
60
61 private:
62 void SaveResultAndFinish(int32_t result) {
63 results_.push_back(result);
64 if (results_.size() == iteration_count_) {
65 integer_service_.reset(); // Must be done on thread_.
66 finished_callback_.Run(this, results_);
67 }
68 }
69
70 ScopedMessagePipeHandle proxy_handle_;
71 base::Thread thread_;
72 IntegerServicePtr integer_service_;
73 DemoTaskFinishedCallback finished_callback_;
74 unsigned iteration_count_;
75 std::vector<int32_t> results_;
76 };
77
78 // Connect to the IntegerService and give its proxy to the
79 // IndirectIntegerService. Start kTaskCount DemoTask threads all of
80 // which will use the IndirectIntegerService to get their own connection
81 // to the (one) IntegerService. Each DemoTask will call the IntegerService's
82 // Increment() method kTaskIterationCount times, collect the results in
83 // a vector and return them to FinishDemoTask.
84 //
85 // The IntegerService, whose value is initially 0, will be called a total of
86 // N = |kTaskCount * kTaskIterationCount| times. Each DemoTask's results
87 // are displayed in array of length N. Digits appear in positions that
88 // correspond to the results obtained by the DemoTask thread. The results
89 // show that the DemoTask threads are accessing the Integer in parallel.
90 // The fact that only one digit appears in each column shows that things
91 // are working correctly.
92 class IndirectServiceDemoAppDelegate : public ApplicationDelegate {
93 public:
94 void Initialize(ApplicationImpl* app) override {
95 IntegerServicePtr indirect_service_delegate;
96 app->ConnectToService("mojo:indirect_integer_service",
97 &indirect_integer_service_);
98 app->ConnectToService("mojo:integer_service", &indirect_service_delegate);
99 indirect_integer_service_->Set(indirect_service_delegate.Pass());
100
101 for (unsigned i = 0; i < kTaskCount; i++) {
102 IntegerServicePtr integer_service;
103 indirect_integer_service_->Get(GetProxy(&integer_service));
104 DemoTaskFinishedCallback finished_callback = base::Bind(
105 &IndirectServiceDemoAppDelegate::FinishDemoTask,
106 base::Unretained(this),
107 base::Unretained(base::MessageLoop::current()));
108 // We're passing the integer_service_ proxy to another thread, so
109 // use its MessagePipe.
110 tasks_.push_back(new DemoTask(integer_service.PassMessagePipe(),
111 finished_callback,
112 kTaskIterationCount));
113 }
114 }
115
116 private:
117 static const unsigned kTaskCount = 10;
118 static const unsigned kTaskIterationCount = 6;
119
120 // This method is called on a DemoTask thread. It just calls DoFinishDemoTask
121 // on the application's run loop. Doing so serializes the DoFinishDemoTask
122 // calls.
123 void FinishDemoTask(base::MessageLoop *run_loop,
124 DemoTask* task,
125 const std::vector<int32_t>& results) {
126 run_loop->PostTask(FROM_HERE, base::Bind(
127 &IndirectServiceDemoAppDelegate::DoFinishDemoTask,
128 base::Unretained(this),
129 base::Unretained(task),
130 results));
131 }
132
133 void DoFinishDemoTask(DemoTask* task, const std::vector<int32_t>& results) {
134 std::string display(kTaskCount * kTaskIterationCount, ' ');
135 for (unsigned i = 0; i < results.size(); i++)
136 display[results[i]] = '0' + (results[i] % 10);
137 printf("DemoTask Thread [%s]\n", display.c_str());
138 tasks_.erase(std::remove(tasks_.begin(), tasks_.end(), task), tasks_.end());
139 delete task; // Stop the DemoTask's thread etc.
140 if (tasks_.empty())
141 ApplicationImpl::Terminate();
142 }
143
144 IndirectIntegerServicePtr indirect_integer_service_;
145 std::vector<DemoTask*> tasks_;
146 };
147
148
149 } // namespace examples
150 } // namespace mojo
151
152 MojoResult MojoMain(MojoHandle shell_handle) {
153 mojo::ApplicationRunnerChromium runner(
154 new mojo::examples::IndirectServiceDemoAppDelegate);
155 return runner.Run(shell_handle);
156 }
OLDNEW
« no previous file with comments | « examples/indirect_service/indirect_integer_service.cc ('k') | examples/indirect_service/indirect_service_demo.mojom » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698