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

Side by Side Diff: mojo/service_manager/background_shell_service_loader.cc

Issue 437493002: mojo: allow BackgroundServiceLoader-loaded apps to Quit themselves. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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
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 "mojo/service_manager/background_service_loader.h" 5 #include "mojo/service_manager/background_shell_service_loader.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "mojo/service_manager/service_manager.h" 8 #include "mojo/service_manager/service_manager.h"
9 9
10 namespace mojo { 10 namespace mojo {
11 11
12 class BackgroundServiceLoader::BackgroundLoader { 12 namespace {
13
14 void QuitLoop() {
15 base::MessageLoop::current()->Quit();
sky 2014/07/31 20:59:33 Use a RunLoop.
tim (not reviewing) 2014/07/31 22:17:28 Done, assuming you meant Run() a RunLoop in Backgr
sky 2014/08/04 18:56:25 I was actually think you use the base::RunLoop you
tim (not reviewing) 2014/08/04 19:51:29 I see. It'd have to be heap allocated pointer in t
16 }
17
18 } // namespace
19
20 class BackgroundShellServiceLoader::BackgroundLoader {
13 public: 21 public:
14 explicit BackgroundLoader(ServiceLoader* loader) : loader_(loader) {} 22 explicit BackgroundLoader(ServiceLoader* loader) : loader_(loader) {}
15 ~BackgroundLoader() {} 23 ~BackgroundLoader() {}
16 24
17 void LoadService(ServiceManager* manager, 25 void LoadService(ServiceManager* manager,
18 const GURL& url, 26 const GURL& url,
19 ScopedMessagePipeHandle shell_handle) { 27 ScopedMessagePipeHandle shell_handle) {
20 loader_->LoadService(manager, url, shell_handle.Pass()); 28 loader_->LoadService(manager, url, shell_handle.Pass());
21 } 29 }
22 30
23 void OnServiceError(ServiceManager* manager, const GURL& url) { 31 void OnServiceError(ServiceManager* manager, const GURL& url) {
24 loader_->OnServiceError(manager, url); 32 loader_->OnServiceError(manager, url);
25 } 33 }
26 34
27 private: 35 private:
28 base::MessageLoop::Type message_loop_type_; 36 ServiceLoader* loader_; // Owned by BackgroundShellServiceLoader
29 ServiceLoader* loader_; // Owned by BackgroundServiceLoader
30 37
31 DISALLOW_COPY_AND_ASSIGN(BackgroundLoader); 38 DISALLOW_COPY_AND_ASSIGN(BackgroundLoader);
32 }; 39 };
33 40
34 BackgroundServiceLoader::BackgroundServiceLoader( 41 BackgroundShellServiceLoader::BackgroundShellServiceLoader(
35 scoped_ptr<ServiceLoader> real_loader, 42 scoped_ptr<ServiceLoader> real_loader,
36 const char* thread_name, 43 const std::string& thread_name,
37 base::MessageLoop::Type message_loop_type) 44 base::MessageLoop::Type message_loop_type)
38 : loader_(real_loader.Pass()), 45 : quit_on_shutdown_(false),
39 thread_(thread_name), 46 loaded_service_(false),
47 loader_(real_loader.Pass()),
40 message_loop_type_(message_loop_type), 48 message_loop_type_(message_loop_type),
49 message_loop_created_(true, false),
50 thread_(this, thread_name),
41 background_loader_(NULL) { 51 background_loader_(NULL) {
52 // TODO(tim): It'd be nice if we could just have each LoadService call result
53 // in a new thread like DynamicService{Loader, Runner}. But some loaders are
54 // creating multiple ApplicationImpls (NetworkServiceLoader) sharing a
55 // delegate (etc). So we have to keep it single threaded, wait for the
56 // thread to initialize, and post to the TaskRunner for subsequent LoadService
57 // calls for now.
58 thread_.Start();
59 message_loop_created_.Wait();
sky 2014/07/31 20:59:33 Why do we need to block here? Or for that matter s
tim (not reviewing) 2014/07/31 22:17:28 DelegateSimpleThread requires that it is both Star
60 DCHECK(task_runner_);
42 } 61 }
43 62
44 BackgroundServiceLoader::~BackgroundServiceLoader() { 63 BackgroundShellServiceLoader::~BackgroundShellServiceLoader() {
45 if (thread_.IsRunning()) { 64 if (quit_on_shutdown_ || !loaded_service_)
46 thread_.message_loop()->PostTask( 65 task_runner_->PostTask(FROM_HERE, base::Bind(&QuitLoop));
47 FROM_HERE, 66 thread_.Join();
48 base::Bind(&BackgroundServiceLoader::ShutdownOnBackgroundThread,
49 base::Unretained(this)));
50 }
51 thread_.Stop();
52 } 67 }
53 68
54 void BackgroundServiceLoader::LoadService( 69 void BackgroundShellServiceLoader::LoadService(
55 ServiceManager* manager, 70 ServiceManager* manager,
56 const GURL& url, 71 const GURL& url,
57 ScopedMessagePipeHandle shell_handle) { 72 ScopedMessagePipeHandle shell_handle) {
58 const int kDefaultStackSize = 0; 73 loaded_service_ = true;
59 if (!thread_.IsRunning()) { 74 task_runner_->PostTask(FROM_HERE,
60 thread_.StartWithOptions( 75 base::Bind(&BackgroundShellServiceLoader::LoadServiceOnBackgroundThread,
61 base::Thread::Options(message_loop_type_, kDefaultStackSize));
62 }
63 thread_.message_loop()->PostTask(
64 FROM_HERE,
65 base::Bind(&BackgroundServiceLoader::LoadServiceOnBackgroundThread,
66 base::Unretained(this), manager, url, 76 base::Unretained(this), manager, url,
67 base::Owned( 77 base::Owned(
68 new ScopedMessagePipeHandle(shell_handle.Pass())))); 78 new ScopedMessagePipeHandle(shell_handle.Pass()))));
69 } 79 }
70 80
71 void BackgroundServiceLoader::OnServiceError(ServiceManager* manager, 81 void BackgroundShellServiceLoader::OnServiceError(
72 const GURL& url) { 82 ServiceManager* manager, const GURL& url) {
73 if (!thread_.IsRunning()) 83 task_runner_->PostTask(FROM_HERE,
74 thread_.Start(); 84 base::Bind(
75 thread_.message_loop()->PostTask( 85 &BackgroundShellServiceLoader::OnServiceErrorOnBackgroundThread,
76 FROM_HERE, 86 base::Unretained(this), manager, url));
77 base::Bind(&BackgroundServiceLoader::OnServiceErrorOnBackgroundThread,
78 base::Unretained(this), manager, url));
79 } 87 }
80 88
81 void BackgroundServiceLoader::LoadServiceOnBackgroundThread( 89 void BackgroundShellServiceLoader::Run() {
82 ServiceManager* manager, 90 scoped_ptr<base::MessageLoop> message_loop;
sky 2014/07/31 20:59:33 You should be able to use MessageLoop(type) here.
tim (not reviewing) 2014/07/31 22:17:28 Ah.. forgot about that. Thanks!
83 const GURL& url, 91 switch (message_loop_type_) {
84 ScopedMessagePipeHandle* shell_handle) { 92 case base::MessageLoop::TYPE_UI:
93 message_loop.reset(new base::MessageLoopForUI());
94 break;
95 case base::MessageLoop::TYPE_IO:
96 message_loop.reset(new base::MessageLoopForIO());
97 break;
98 case base::MessageLoop::TYPE_DEFAULT:
99 message_loop.reset(new base::MessageLoop());
100 break;
101 default:
102 NOTREACHED();
103 }
104 task_runner_ = message_loop->task_runner();
105 message_loop_created_.Signal();
106 message_loop->Run();
107
108 delete background_loader_;
109 background_loader_ = NULL;
110 // Destroy |loader_| on the thread it's actually used on.
111 loader_.reset();
112 }
113
114 void BackgroundShellServiceLoader::LoadServiceOnBackgroundThread(
115 ServiceManager* manager,
116 const GURL& url,
117 ScopedMessagePipeHandle* shell_handle) {
118 DCHECK(task_runner_->RunsTasksOnCurrentThread());
85 if (!background_loader_) 119 if (!background_loader_)
86 background_loader_ = new BackgroundLoader(loader_.get()); 120 background_loader_ = new BackgroundLoader(loader_.get());
87 background_loader_->LoadService( 121 background_loader_->LoadService(manager, url, shell_handle->Pass());
88 manager, url, shell_handle->Pass());
89 } 122 }
90 123
91 void BackgroundServiceLoader::OnServiceErrorOnBackgroundThread( 124 void BackgroundShellServiceLoader::OnServiceErrorOnBackgroundThread(
92 ServiceManager* manager, 125 ServiceManager* manager, const GURL& url) {
93 const GURL& url) { 126 DCHECK(task_runner_->RunsTasksOnCurrentThread());
94 if (!background_loader_) 127 if (!background_loader_)
95 background_loader_ = new BackgroundLoader(loader_.get()); 128 background_loader_ = new BackgroundLoader(loader_.get());
96 background_loader_->OnServiceError(manager, url); 129 background_loader_->OnServiceError(manager, url);
97 } 130 }
98 131
99 void BackgroundServiceLoader::ShutdownOnBackgroundThread() {
100 delete background_loader_;
101 // Destroy |loader_| on the thread it's actually used on.
102 loader_.reset();
103 }
104
105 } // namespace mojo 132 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698