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

Unified 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: 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 side-by-side diff with in-line comments
Download patch
Index: examples/indirect_service/indirect_service_demo.cc
diff --git a/examples/indirect_service/indirect_service_demo.cc b/examples/indirect_service/indirect_service_demo.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a11d3e5adbedaf93c682201785aa44235eb052fa
--- /dev/null
+++ b/examples/indirect_service/indirect_service_demo.cc
@@ -0,0 +1,148 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstdlib>
+
+#include "base/bind.h"
+#include "base/memory/scoped_vector.h"
+#include "base/message_loop/message_loop.h"
+#include "base/threading/thread.h"
+#include "base/time/time.h"
+#include "examples/indirect_service/indirect_service_demo.mojom.h"
+#include "mojo/application/application_runner_chromium.h"
+#include "mojo/public/c/system/main.h"
+#include "mojo/public/cpp/application/application_delegate.h"
+#include "mojo/public/cpp/application/application_impl.h"
+
+namespace mojo {
+namespace examples {
+
+class DemoTask;
+
+typedef typename base::Callback<void(DemoTask*, const std::vector<int32_t>&)>
+ DemoTaskFinishedCallback;
+
+// A thread that connects to the IndirectIntegerService, gets a connection
+// to its IntegerService, and then calls Increment() iteration_count times.
+// The results are saved and returned with the finished_callback.
+class DemoTask {
+ public:
+ DemoTask(ScopedMessagePipeHandle proxy_handle,
+ const DemoTaskFinishedCallback& finished_callback,
+ unsigned iteration_count)
+ : proxy_handle_(proxy_handle.Pass()),
+ thread_("DemoTask"),
+ finished_callback_(finished_callback),
+ iteration_count_(iteration_count) {
+ thread_.Start();
qsr 2014/11/20 08:49:10 You might want to put a MessagePumpMojo on this th
hansmuller 2014/11/20 17:53:04 I've just tried that. base::Thread::Options o
+ thread_.message_loop()->PostTask(
+ FROM_HERE, base::Bind(&DemoTask::Run, base::Unretained(this)));
yzshen1 2014/11/20 18:17:17 wrong indent.
hansmuller 2014/11/20 19:27:59 Done.
+ }
+
+ void Run() {
+ integer_service_.Bind(proxy_handle_.Pass());
+ base::Callback<void(int32_t)> callback =
+ base::Bind(&DemoTask::SaveResultAndFinish, base::Unretained(this));
+ for(int unsigned i = 0; i < iteration_count_; i++) {
+ integer_service_->Increment(callback);
+ // To ensure that the DemoTask threads' execution overlaps, sleep.
+ base::PlatformThread::Sleep(
+ base::TimeDelta::FromMilliseconds(rand() % 10));
+ }
+ }
+
+ private:
+ void SaveResultAndFinish(int32_t result) {
+ results_.push_back(result);
+ if (results_.size() == iteration_count_)
+ finished_callback_.Run(this, results_);
+ }
+
+ ScopedMessagePipeHandle proxy_handle_;
+ base::Thread thread_;
+ IntegerServicePtr integer_service_;
yzshen1 2014/11/20 18:17:18 This needs to be destroyed on |thread_|.
+ DemoTaskFinishedCallback finished_callback_;
+ unsigned iteration_count_;
+ std::vector<int32_t> results_;
+};
+
+// Connect to the IntegerService and give its proxy to the
+// IndirectIntegerService. Start task_count_ DemoTask threads all of
+// which will use the IndirectIntegerService to get their own connection
+// to the (one) IntegerService. Each DemoTask will call the IntegerService's
+// Increment() method task_iteration_count times, collect the results in
yzshen1 2014/11/20 18:17:17 task_iteration_count_
hansmuller 2014/11/20 19:27:59 Done.
+// a vector and return them to FinishDemoTask.
+//
+// The IntegerService, whose value is initially 0, will be called a total of
+// N = |task_count_ * task_iteration_count_| times. Each DemoTask's results
+// are displayed in array of length N. Digits appear in positions that
+// correspond to the results obtained by the DemoTask thread. The results
+// show that the DemoTask threads are accessing the Integer in parallel.
+// The fact that only digit appears in each column provies that things
Aaron Boodman 2014/11/20 07:21:58 This sentence doesn't parse. Missing the word 'one
hansmuller 2014/11/20 17:53:04 And "provies". Yikes.
hansmuller 2014/11/20 17:53:04 Yes, thanks for reading all of this.
+// are working correctly.
+
Aaron Boodman 2014/11/20 07:21:58 No empty line necessary.
hansmuller 2014/11/20 17:53:04 Done.
+class IndirectServiceDemoAppDelegate : public ApplicationDelegate {
+ public:
+ virtual void Initialize(ApplicationImpl* app) override {
+ IntegerServicePtr indirect_service_delegate;
+ app->ConnectToService("mojo:indirect_integer_service",
+ &indirect_integer_service_);
+ app->ConnectToService("mojo:integer_service", &indirect_service_delegate);
+ indirect_integer_service_->Set(indirect_service_delegate.Pass());
+
+ for (unsigned i = 0; i < task_count_; i++) {
+ IntegerServicePtr integer_service;
+ indirect_integer_service_->Get(GetProxy(&integer_service));
+ DemoTaskFinishedCallback finished_callback = base::Bind(
+ &IndirectServiceDemoAppDelegate::FinishDemoTask,
+ base::Unretained(this),
+ base::Unretained(base::MessageLoop::current()));
+ // We're passing the integer_service proxy to another thread, to
+ // use its MessagePipe.
+ tasks_.push_back(new DemoTask(integer_service.PassMessagePipe(),
yzshen1 2014/11/20 18:17:17 Who owns these DemoTask instances?
+ finished_callback,
+ task_iteration_count_));
+ }
+ }
+
+ private:
+ const unsigned task_count_ = 10;
yzshen1 2014/11/20 18:17:17 Maybe consider "static const" and name them kTaskC
hansmuller 2014/11/20 19:27:59 Done.
+ const unsigned task_iteration_count_ = 6;
+
+ // This method is called on a DemoTask thread. It just calls DoFinishDemoTask
+ // on the application's run loop. Doing so serializes the DoFinishDemoTask
+ // calls.
+ void FinishDemoTask(base::MessageLoop *run_loop,
+ DemoTask* task,
+ const std::vector<int32_t>& results) {
+ run_loop->PostTask(FROM_HERE, base::Bind(
+ &IndirectServiceDemoAppDelegate::DoFinishDemoTask,
+ base::Unretained(this),
+ base::Unretained(task),
+ results));
+ }
+
+ void DoFinishDemoTask(DemoTask* task, const std::vector<int32_t>& results) {
+ std::string display(task_count_ * task_iteration_count_, ' ');
+ for (unsigned i = 0; i < results.size(); i++)
+ display[results[i]] = '0' + (results[i] % 10);
+ printf("DemoTask Thread [%s]\n", display.c_str());
+ tasks_.erase(std::remove(tasks_.begin(), tasks_.end(), task), tasks_.end());
+ if (tasks_.empty())
+ ApplicationImpl::Terminate();
+ }
+
+ IndirectIntegerServicePtr indirect_integer_service_;
+ std::vector<DemoTask*> tasks_;
+};
+
+
+} // namespace examples
+} // namespace mojo
+
+MojoResult MojoMain(MojoHandle shell_handle) {
+ mojo::ApplicationRunnerChromium runner(
+ new mojo::examples::IndirectServiceDemoAppDelegate);
+ return runner.Run(shell_handle);
+}

Powered by Google App Engine
This is Rietveld 408576698