OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 "content/child/background_sync/background_sync_provider_thread_proxy.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "base/lazy_instance.h" | |
10 #include "base/location.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/single_thread_task_runner.h" | |
13 #include "base/threading/thread_local.h" | |
14 #include "content/child/background_sync/background_sync_provider.h" | |
15 | |
16 using base::LazyInstance; | |
17 using base::ThreadLocalPointer; | |
18 | |
19 namespace content { | |
20 | |
21 namespace { | |
22 | |
23 template <typename T> | |
24 struct WebCallbacksMatcher; | |
25 | |
26 template <typename Stype, typename Ttype> | |
27 struct WebCallbacksMatcher<blink::WebCallbacks<Stype, Ttype>> { | |
28 using S = Stype; | |
29 using T = Ttype; | |
30 using WebCallbacks = typename blink::WebCallbacks<S, T>; | |
31 }; | |
32 | |
33 // CallbackThreadAdapter<WebCallbacks<S, T>> is a wrapper for WebCallbacks<S, T> | |
34 // which switches to a specific thread before calling the wrapped callback's | |
35 // onSuccess or onError methods. | |
36 // | |
37 // Takes ownership of the WebCallbacks object which it wraps. | |
38 template <typename X> | |
39 class CallbackThreadAdapter : public WebCallbacksMatcher<X>::WebCallbacks { | |
40 using S = typename WebCallbacksMatcher<X>::S; | |
41 using T = typename WebCallbacksMatcher<X>::T; | |
42 using OnSuccessType = void (blink::WebCallbacks<S, T>::*)(S); | |
43 using OnErrorType = void (blink::WebCallbacks<S, T>::*)(T); | |
44 | |
45 public: | |
46 CallbackThreadAdapter(scoped_ptr<blink::WebCallbacks<S, T>> callbacks, | |
47 int worker_thread_id) | |
48 : worker_thread_id_(worker_thread_id) { | |
49 callbacks_.reset(callbacks.release()); | |
50 } | |
51 | |
52 virtual void onSuccess(S results) { | |
53 OnSuccessType on_success = &blink::WebCallbacks<S, T>::onSuccess; | |
54 // If the worker thread has been destroyed, then this task will be | |
55 // silently discarded. | |
56 WorkerTaskRunner::Instance()->PostTask( | |
57 worker_thread_id_, | |
58 base::Bind(on_success, base::Owned(callbacks_.release()), results)); | |
59 } | |
60 | |
61 virtual void onError(T error) { | |
62 OnErrorType on_error = &blink::WebCallbacks<S, T>::onError; | |
63 // If the worker thread has been destroyed, then this task will be | |
64 // silently discarded. | |
65 WorkerTaskRunner::Instance()->PostTask( | |
66 worker_thread_id_, | |
67 base::Bind(on_error, base::Owned(callbacks_.release()), error)); | |
68 } | |
69 | |
70 private: | |
71 scoped_ptr<blink::WebCallbacks<S, T>> callbacks_; | |
72 int worker_thread_id_; | |
73 }; | |
74 | |
75 LazyInstance<ThreadLocalPointer<BackgroundSyncProviderThreadProxy>>::Leaky | |
76 g_sync_provider_tls = LAZY_INSTANCE_INITIALIZER; | |
77 | |
78 void DuplicateRegistrationHandleCallbackOnSWThread( | |
79 const BackgroundSyncProviderThreadProxy:: | |
80 DuplicateRegistrationHandleCallback& callback, | |
81 BackgroundSyncError error, | |
82 SyncRegistrationPtr registration) { | |
83 callback.Run(error, registration.Pass()); | |
84 } | |
85 | |
86 void DuplicateRegistrationHandleCallbackOnMainThread( | |
87 int worker_thread_id, | |
88 const BackgroundSyncProviderThreadProxy:: | |
89 DuplicateRegistrationHandleCallback& callback, | |
90 BackgroundSyncError error, | |
91 SyncRegistrationPtr registration) { | |
92 WorkerTaskRunner::Instance()->PostTask( | |
93 worker_thread_id, | |
94 base::Bind(&DuplicateRegistrationHandleCallbackOnSWThread, callback, | |
95 error, base::Passed(registration.Pass()))); | |
96 } | |
97 | |
98 } // anonymous namespace | |
99 | |
100 // static | |
101 BackgroundSyncProviderThreadProxy* | |
102 BackgroundSyncProviderThreadProxy::GetThreadInstance( | |
103 base::SingleThreadTaskRunner* main_thread_task_runner, | |
104 BackgroundSyncProvider* sync_provider) { | |
105 if (g_sync_provider_tls.Pointer()->Get()) | |
106 return g_sync_provider_tls.Pointer()->Get(); | |
107 | |
108 if (!WorkerThread::GetCurrentId()) { | |
109 // This could happen if GetThreadInstance is called very late (say by a | |
110 // garbage collected SyncRegistration). | |
111 return nullptr; | |
112 } | |
113 | |
114 BackgroundSyncProviderThreadProxy* instance = | |
115 new BackgroundSyncProviderThreadProxy(main_thread_task_runner, | |
116 sync_provider); | |
117 WorkerThread::AddObserver(instance); | |
118 return instance; | |
119 } | |
120 | |
121 void BackgroundSyncProviderThreadProxy::registerBackgroundSync( | |
122 const blink::WebSyncRegistration* options, | |
123 blink::WebServiceWorkerRegistration* service_worker_registration, | |
124 bool requested_from_service_worker, | |
125 blink::WebSyncRegistrationCallbacks* callbacks) { | |
126 DCHECK(options); | |
127 DCHECK(service_worker_registration); | |
128 DCHECK(callbacks); | |
129 main_thread_task_runner_->PostTask( | |
130 FROM_HERE, | |
131 base::Bind( | |
132 &BackgroundSyncProvider::registerBackgroundSync, | |
133 base::Unretained(sync_provider_), options, | |
134 service_worker_registration, requested_from_service_worker, | |
135 new CallbackThreadAdapter<blink::WebSyncRegistrationCallbacks>( | |
136 make_scoped_ptr(callbacks), WorkerThread::GetCurrentId()))); | |
137 } | |
138 | |
139 void BackgroundSyncProviderThreadProxy::unregisterBackgroundSync( | |
140 blink::WebSyncRegistration::Periodicity periodicity, | |
141 int64_t id, | |
142 const blink::WebString& tag, | |
143 blink::WebServiceWorkerRegistration* service_worker_registration, | |
144 blink::WebSyncUnregistrationCallbacks* callbacks) { | |
145 DCHECK(service_worker_registration); | |
146 DCHECK(callbacks); | |
147 main_thread_task_runner_->PostTask( | |
148 FROM_HERE, | |
149 base::Bind( | |
150 &BackgroundSyncProvider::unregisterBackgroundSync, | |
151 base::Unretained(sync_provider_), periodicity, id, | |
152 // We cast WebString to string16 before crossing threads | |
153 // for thread-safety. | |
154 static_cast<base::string16>(tag), service_worker_registration, | |
155 new CallbackThreadAdapter<blink::WebSyncUnregistrationCallbacks>( | |
156 make_scoped_ptr(callbacks), WorkerThread::GetCurrentId()))); | |
157 } | |
158 | |
159 void BackgroundSyncProviderThreadProxy::getRegistration( | |
160 blink::WebSyncRegistration::Periodicity periodicity, | |
161 const blink::WebString& tag, | |
162 blink::WebServiceWorkerRegistration* service_worker_registration, | |
163 blink::WebSyncRegistrationCallbacks* callbacks) { | |
164 DCHECK(service_worker_registration); | |
165 DCHECK(callbacks); | |
166 main_thread_task_runner_->PostTask( | |
167 FROM_HERE, | |
168 base::Bind( | |
169 &BackgroundSyncProvider::getRegistration, | |
170 base::Unretained(sync_provider_), periodicity, | |
171 // We cast WebString to string16 before crossing threads | |
172 // for thread-safety. | |
173 static_cast<base::string16>(tag), service_worker_registration, | |
174 new CallbackThreadAdapter<blink::WebSyncRegistrationCallbacks>( | |
175 make_scoped_ptr(callbacks), WorkerThread::GetCurrentId()))); | |
176 } | |
177 | |
178 void BackgroundSyncProviderThreadProxy::getRegistrations( | |
179 blink::WebSyncRegistration::Periodicity periodicity, | |
180 blink::WebServiceWorkerRegistration* service_worker_registration, | |
181 blink::WebSyncGetRegistrationsCallbacks* callbacks) { | |
182 DCHECK(service_worker_registration); | |
183 DCHECK(callbacks); | |
184 main_thread_task_runner_->PostTask( | |
185 FROM_HERE, | |
186 base::Bind( | |
187 &BackgroundSyncProvider::getRegistrations, | |
188 base::Unretained(sync_provider_), periodicity, | |
189 service_worker_registration, | |
190 new CallbackThreadAdapter<blink::WebSyncGetRegistrationsCallbacks>( | |
191 make_scoped_ptr(callbacks), WorkerThread::GetCurrentId()))); | |
192 } | |
193 | |
194 void BackgroundSyncProviderThreadProxy::getPermissionStatus( | |
195 blink::WebSyncRegistration::Periodicity periodicity, | |
196 blink::WebServiceWorkerRegistration* service_worker_registration, | |
197 blink::WebSyncGetPermissionStatusCallbacks* callbacks) { | |
198 DCHECK(service_worker_registration); | |
199 DCHECK(callbacks); | |
200 main_thread_task_runner_->PostTask( | |
201 FROM_HERE, | |
202 base::Bind( | |
203 &BackgroundSyncProvider::getPermissionStatus, | |
204 base::Unretained(sync_provider_), periodicity, | |
205 service_worker_registration, | |
206 new CallbackThreadAdapter<blink::WebSyncGetPermissionStatusCallbacks>( | |
207 make_scoped_ptr(callbacks), WorkerThread::GetCurrentId()))); | |
208 } | |
209 | |
210 void BackgroundSyncProviderThreadProxy::releaseRegistration(int64_t handle_id) { | |
211 main_thread_task_runner_->PostTask( | |
212 FROM_HERE, base::Bind(&BackgroundSyncProvider::releaseRegistration, | |
213 base::Unretained(sync_provider_), handle_id)); | |
214 } | |
215 | |
216 void BackgroundSyncProviderThreadProxy::notifyWhenDone( | |
217 int64_t handle_id, | |
218 blink::WebSyncNotifyWhenDoneCallbacks* callbacks) { | |
219 DCHECK(callbacks); | |
220 | |
221 main_thread_task_runner_->PostTask( | |
222 FROM_HERE, | |
223 base::Bind( | |
224 &BackgroundSyncProvider::notifyWhenDone, | |
225 base::Unretained(sync_provider_), handle_id, | |
226 new CallbackThreadAdapter<blink::WebSyncNotifyWhenDoneCallbacks>( | |
227 make_scoped_ptr(callbacks), WorkerThread::GetCurrentId()))); | |
228 } | |
229 | |
230 void BackgroundSyncProviderThreadProxy::DuplicateRegistrationHandle( | |
231 int64 handle_id, | |
232 const DuplicateRegistrationHandleCallback& callback) { | |
233 main_thread_task_runner_->PostTask( | |
234 FROM_HERE, | |
235 base::Bind(&BackgroundSyncProvider::DuplicateRegistrationHandle, | |
236 base::Unretained(sync_provider_), handle_id, | |
237 base::Bind(&DuplicateRegistrationHandleCallbackOnMainThread, | |
238 WorkerThread::GetCurrentId(), callback))); | |
239 } | |
240 | |
241 void BackgroundSyncProviderThreadProxy::WillStopCurrentWorkerThread() { | |
242 delete this; | |
243 } | |
244 | |
245 BackgroundSyncProviderThreadProxy::BackgroundSyncProviderThreadProxy( | |
246 base::SingleThreadTaskRunner* main_thread_task_runner, | |
247 BackgroundSyncProvider* sync_provider) | |
248 : main_thread_task_runner_(main_thread_task_runner), | |
249 sync_provider_(sync_provider) { | |
250 g_sync_provider_tls.Pointer()->Set(this); | |
251 } | |
252 | |
253 BackgroundSyncProviderThreadProxy::~BackgroundSyncProviderThreadProxy() { | |
254 g_sync_provider_tls.Pointer()->Set(nullptr); | |
255 } | |
256 | |
257 } // namespace content | |
OLD | NEW |