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

Side by Side Diff: extensions/browser/api/api_resource_manager.h

Issue 329853010: Additional methods for chrome.logPrivate API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 years, 5 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
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 #ifndef EXTENSIONS_BROWSER_API_API_RESOURCE_MANAGER_H_ 5 #ifndef EXTENSIONS_BROWSER_API_API_RESOURCE_MANAGER_H_
6 #define EXTENSIONS_BROWSER_API_API_RESOURCE_MANAGER_H_ 6 #define EXTENSIONS_BROWSER_API_API_RESOURCE_MANAGER_H_
7 7
8 #include <map> 8 #include <map>
9 9
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
(...skipping 18 matching lines...) Expand all
29 class BluetoothSocketEventDispatcher; 29 class BluetoothSocketEventDispatcher;
30 } 30 }
31 31
32 namespace core_api { 32 namespace core_api {
33 class SerialEventDispatcher; 33 class SerialEventDispatcher;
34 class TCPServerSocketEventDispatcher; 34 class TCPServerSocketEventDispatcher;
35 class TCPSocketEventDispatcher; 35 class TCPSocketEventDispatcher;
36 class UDPSocketEventDispatcher; 36 class UDPSocketEventDispatcher;
37 } 37 }
38 38
39 template <typename T>
40 struct NamedThreadTraits {
41 static bool IsCalledOnValidThread() {
42 return content::BrowserThread::CurrentlyOn(T::kThreadId);
43 }
44
45 static bool IsMessageLoopValid() {
46 return content::BrowserThread::IsMessageLoopValid(T::kThreadId);
47 }
48
49 static scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() {
50 return content::BrowserThread::GetMessageLoopProxyForThread(T::kThreadId);
51 }
52 };
53
54 template <typename T>
55 struct TestThreadTraits {
56 static bool IsCalledOnValidThread() {
57 return content::BrowserThread::CurrentlyOn(thread_id_);
58 }
59
60 static bool IsMessageLoopValid() {
61 return content::BrowserThread::IsMessageLoopValid(thread_id_);
62 }
63
64 static scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() {
65 return content::BrowserThread::GetMessageLoopProxyForThread(thread_id_);
66 }
67
68 static content::BrowserThread::ID thread_id_;
69 };
70
71 template <typename T>
72 content::BrowserThread::ID TestThreadTraits<T>::thread_id_ =
73 content::BrowserThread::IO;
74
39 // An ApiResourceManager manages the lifetime of a set of resources that 75 // An ApiResourceManager manages the lifetime of a set of resources that
40 // ApiFunctions use. Examples are sockets or USB connections. 76 // that live on named threads (i.e. BrowserThread::IO) which ApiFunctions use.
77 // Examples of such resources are sockets or USB connections.
41 // 78 //
42 // Users of this class should define kThreadId to be the thread that 79 // Users of this class should define kThreadId to be the thread that
43 // ApiResourceManager to works on. The default is defined in ApiResource. 80 // ApiResourceManager to works on. The default is defined in ApiResource.
44 // The user must also define a static const char* service_name() that returns 81 // The user must also define a static const char* service_name() that returns
45 // the name of the service, and in order for ApiResourceManager to use 82 // the name of the service, and in order for ApiResourceManager to use
46 // service_name() friend this class. 83 // service_name() friend this class.
47 // 84 //
48 // In the cc file the user must define a GetFactoryInstance() and manage their 85 // In the cc file the user must define a GetFactoryInstance() and manage their
49 // own instances (typically using LazyInstance or Singleton). 86 // own instances (typically using LazyInstance or Singleton).
50 // 87 //
(...skipping 14 matching lines...) Expand all
65 // static base::LazyInstance<BrowserContextKeyedAPIFactory< 102 // static base::LazyInstance<BrowserContextKeyedAPIFactory<
66 // ApiResourceManager<Resource> > > 103 // ApiResourceManager<Resource> > >
67 // g_factory = LAZY_INSTANCE_INITIALIZER; 104 // g_factory = LAZY_INSTANCE_INITIALIZER;
68 // 105 //
69 // 106 //
70 // template <> 107 // template <>
71 // BrowserContextKeyedAPIFactory<ApiResourceManager<Resource> >* 108 // BrowserContextKeyedAPIFactory<ApiResourceManager<Resource> >*
72 // ApiResourceManager<Resource>::GetFactoryInstance() { 109 // ApiResourceManager<Resource>::GetFactoryInstance() {
73 // return g_factory.Pointer(); 110 // return g_factory.Pointer();
74 // } 111 // }
75 template <class T> 112 template <class T, typename ThreadingTraits = NamedThreadTraits<T> >
76 class ApiResourceManager : public BrowserContextKeyedAPI, 113 class ApiResourceManager : public BrowserContextKeyedAPI,
77 public base::NonThreadSafe, 114 public base::NonThreadSafe,
78 public content::NotificationObserver { 115 public content::NotificationObserver {
79 public: 116 public:
80 explicit ApiResourceManager(content::BrowserContext* context) 117 explicit ApiResourceManager(content::BrowserContext* context)
81 : thread_id_(T::kThreadId), data_(new ApiResourceData(thread_id_)) { 118 : data_(new ApiResourceData()) {
82 registrar_.Add(this, 119 registrar_.Add(this,
83 chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 120 chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
84 content::NotificationService::AllSources()); 121 content::NotificationService::AllSources());
85 registrar_.Add(this, 122 registrar_.Add(this,
86 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, 123 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
87 content::NotificationService::AllSources()); 124 content::NotificationService::AllSources());
88 } 125 }
89
90 // For Testing. 126 // For Testing.
91 static ApiResourceManager<T>* CreateApiResourceManagerForTest( 127 static ApiResourceManager<T, TestThreadTraits<T> >*
92 content::BrowserContext* context, 128 CreateApiResourceManagerForTest(content::BrowserContext* context,
93 content::BrowserThread::ID thread_id) { 129 content::BrowserThread::ID thread_id) {
94 ApiResourceManager* manager = new ApiResourceManager<T>(context); 130 TestThreadTraits<T>::thread_id_ = thread_id;
95 manager->thread_id_ = thread_id; 131 ApiResourceManager<T, TestThreadTraits<T> >* manager =
96 manager->data_ = new ApiResourceData(thread_id); 132 new ApiResourceManager<T, TestThreadTraits<T> >(context);
97 return manager; 133 return manager;
98 } 134 }
99 135
100 virtual ~ApiResourceManager() { 136 virtual ~ApiResourceManager() {
101 DCHECK(CalledOnValidThread()); 137 DCHECK(CalledOnValidThread());
102 DCHECK(content::BrowserThread::IsMessageLoopValid(thread_id_)) 138 DCHECK(ThreadingTraits::IsMessageLoopValid())
103 << "A unit test is using an ApiResourceManager but didn't provide " 139 << "A unit test is using an ApiResourceManager but didn't provide "
104 "the thread message loop needed for that kind of resource. " 140 "the thread message loop needed for that kind of resource. "
105 "Please ensure that the appropriate message loop is operational."; 141 "Please ensure that the appropriate message loop is operational.";
106 142
107 data_->InititateCleanup(); 143 data_->InititateCleanup();
108 } 144 }
109 145
110 // BrowserContextKeyedAPI implementation.
111 static BrowserContextKeyedAPIFactory<ApiResourceManager<T> >*
112 GetFactoryInstance();
113
114 // Convenience method to get the ApiResourceManager for a profile.
115 static ApiResourceManager<T>* Get(content::BrowserContext* context) {
116 return BrowserContextKeyedAPIFactory<ApiResourceManager<T> >::Get(context);
117 }
118
119 // Takes ownership. 146 // Takes ownership.
120 int Add(T* api_resource) { return data_->Add(api_resource); } 147 int Add(T* api_resource) { return data_->Add(api_resource); }
121 148
122 void Remove(const std::string& extension_id, int api_resource_id) { 149 void Remove(const std::string& extension_id, int api_resource_id) {
123 data_->Remove(extension_id, api_resource_id); 150 data_->Remove(extension_id, api_resource_id);
124 } 151 }
125 152
126 T* Get(const std::string& extension_id, int api_resource_id) { 153 T* Get(const std::string& extension_id, int api_resource_id) {
127 return data_->Get(extension_id, api_resource_id); 154 return data_->Get(extension_id, api_resource_id);
128 } 155 }
129 156
130 base::hash_set<int>* GetResourceIds(const std::string& extension_id) { 157 base::hash_set<int>* GetResourceIds(const std::string& extension_id) {
131 return data_->GetResourceIds(extension_id); 158 return data_->GetResourceIds(extension_id);
132 } 159 }
133 160
161 // BrowserContextKeyedAPI implementation.
162 static BrowserContextKeyedAPIFactory<ApiResourceManager<T> >*
163 GetFactoryInstance();
164
165 // Convenience method to get the ApiResourceManager for a profile.
166 static ApiResourceManager<T>* Get(content::BrowserContext* context) {
167 return BrowserContextKeyedAPIFactory<ApiResourceManager<T> >::Get(context);
168 }
169
170 // BrowserContextKeyedAPI implementation.
171 static const char* service_name() { return T::service_name(); }
172
134 protected: 173 protected:
135 // content::NotificationObserver: 174 // content::NotificationObserver:
136 virtual void Observe(int type, 175 virtual void Observe(int type,
137 const content::NotificationSource& source, 176 const content::NotificationSource& source,
138 const content::NotificationDetails& details) OVERRIDE { 177 const content::NotificationDetails& details) OVERRIDE {
139 switch (type) { 178 switch (type) {
140 case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: { 179 case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
141 std::string id = content::Details<extensions::UnloadedExtensionInfo>( 180 std::string id = content::Details<extensions::UnloadedExtensionInfo>(
142 details)->extension->id(); 181 details)->extension->id();
143 data_->InitiateExtensionUnloadedCleanup(id); 182 data_->InitiateExtensionUnloadedCleanup(id);
(...skipping 12 matching lines...) Expand all
156 // we could avoid maintaining a friends list here. 195 // we could avoid maintaining a friends list here.
157 friend class BluetoothAPI; 196 friend class BluetoothAPI;
158 friend class api::BluetoothSocketApiFunction; 197 friend class api::BluetoothSocketApiFunction;
159 friend class api::BluetoothSocketEventDispatcher; 198 friend class api::BluetoothSocketEventDispatcher;
160 friend class core_api::SerialEventDispatcher; 199 friend class core_api::SerialEventDispatcher;
161 friend class core_api::TCPServerSocketEventDispatcher; 200 friend class core_api::TCPServerSocketEventDispatcher;
162 friend class core_api::TCPSocketEventDispatcher; 201 friend class core_api::TCPSocketEventDispatcher;
163 friend class core_api::UDPSocketEventDispatcher; 202 friend class core_api::UDPSocketEventDispatcher;
164 friend class BrowserContextKeyedAPIFactory<ApiResourceManager<T> >; 203 friend class BrowserContextKeyedAPIFactory<ApiResourceManager<T> >;
165 204
166 // BrowserContextKeyedAPI implementation.
167 static const char* service_name() { return T::service_name(); }
168
169 static const bool kServiceHasOwnInstanceInIncognito = true; 205 static const bool kServiceHasOwnInstanceInIncognito = true;
170 static const bool kServiceIsNULLWhileTesting = true; 206 static const bool kServiceIsNULLWhileTesting = true;
171 207
172 // ApiResourceData class handles resource bookkeeping on a thread 208 // ApiResourceData class handles resource bookkeeping on a thread
173 // where resource lifetime is handled. 209 // where resource lifetime is handled.
174 class ApiResourceData : public base::RefCountedThreadSafe<ApiResourceData> { 210 class ApiResourceData : public base::RefCountedThreadSafe<ApiResourceData> {
175 public: 211 public:
176 typedef std::map<int, linked_ptr<T> > ApiResourceMap; 212 typedef std::map<int, linked_ptr<T> > ApiResourceMap;
177 // Lookup map from extension id's to allocated resource id's. 213 // Lookup map from extension id's to allocated resource id's.
178 typedef std::map<std::string, base::hash_set<int> > ExtensionToResourceMap; 214 typedef std::map<std::string, base::hash_set<int> > ExtensionToResourceMap;
179 215
180 explicit ApiResourceData(const content::BrowserThread::ID thread_id) 216 ApiResourceData() : next_id_(1) {}
181 : next_id_(1), thread_id_(thread_id) {}
182 217
183 int Add(T* api_resource) { 218 int Add(T* api_resource) {
184 DCHECK_CURRENTLY_ON(thread_id_); 219 DCHECK(ThreadingTraits::IsCalledOnValidThread());
185 int id = GenerateId(); 220 int id = GenerateId();
186 if (id > 0) { 221 if (id > 0) {
187 linked_ptr<T> resource_ptr(api_resource); 222 linked_ptr<T> resource_ptr(api_resource);
188 api_resource_map_[id] = resource_ptr; 223 api_resource_map_[id] = resource_ptr;
189 224
190 const std::string& extension_id = api_resource->owner_extension_id(); 225 const std::string& extension_id = api_resource->owner_extension_id();
191 if (extension_resource_map_.find(extension_id) == 226 if (extension_resource_map_.find(extension_id) ==
192 extension_resource_map_.end()) { 227 extension_resource_map_.end()) {
193 extension_resource_map_[extension_id] = base::hash_set<int>(); 228 extension_resource_map_[extension_id] = base::hash_set<int>();
194 } 229 }
195 extension_resource_map_[extension_id].insert(id); 230 extension_resource_map_[extension_id].insert(id);
196 231
197 return id; 232 return id;
198 } 233 }
199 return 0; 234 return 0;
200 } 235 }
201 236
202 void Remove(const std::string& extension_id, int api_resource_id) { 237 void Remove(const std::string& extension_id, int api_resource_id) {
203 DCHECK_CURRENTLY_ON(thread_id_); 238 DCHECK(ThreadingTraits::IsCalledOnValidThread());
204 if (GetOwnedResource(extension_id, api_resource_id) != NULL) { 239 if (GetOwnedResource(extension_id, api_resource_id) != NULL) {
205 DCHECK(extension_resource_map_.find(extension_id) != 240 DCHECK(extension_resource_map_.find(extension_id) !=
206 extension_resource_map_.end()); 241 extension_resource_map_.end());
207 extension_resource_map_[extension_id].erase(api_resource_id); 242 extension_resource_map_[extension_id].erase(api_resource_id);
208 api_resource_map_.erase(api_resource_id); 243 api_resource_map_.erase(api_resource_id);
209 } 244 }
210 } 245 }
211 246
212 T* Get(const std::string& extension_id, int api_resource_id) { 247 T* Get(const std::string& extension_id, int api_resource_id) {
213 DCHECK_CURRENTLY_ON(thread_id_); 248 DCHECK(ThreadingTraits::IsCalledOnValidThread());
214 return GetOwnedResource(extension_id, api_resource_id); 249 return GetOwnedResource(extension_id, api_resource_id);
215 } 250 }
216 251
217 base::hash_set<int>* GetResourceIds(const std::string& extension_id) { 252 base::hash_set<int>* GetResourceIds(const std::string& extension_id) {
218 DCHECK_CURRENTLY_ON(thread_id_); 253 DCHECK(ThreadingTraits::IsCalledOnValidThread());
219 return GetOwnedResourceIds(extension_id); 254 return GetOwnedResourceIds(extension_id);
220 } 255 }
221 256
222 void InitiateExtensionUnloadedCleanup(const std::string& extension_id) { 257 void InitiateExtensionUnloadedCleanup(const std::string& extension_id) {
223 if (content::BrowserThread::CurrentlyOn(thread_id_)) { 258 if (ThreadingTraits::IsCalledOnValidThread()) {
224 CleanupResourcesFromUnloadedExtension(extension_id); 259 CleanupResourcesFromUnloadedExtension(extension_id);
225 } else { 260 } else {
226 content::BrowserThread::PostTask( 261 ThreadingTraits::GetSequencedTaskRunner()->PostTask(
227 thread_id_,
228 FROM_HERE, 262 FROM_HERE,
229 base::Bind(&ApiResourceData::CleanupResourcesFromUnloadedExtension, 263 base::Bind(&ApiResourceData::CleanupResourcesFromUnloadedExtension,
230 this, 264 this,
231 extension_id)); 265 extension_id));
232 } 266 }
233 } 267 }
234 268
235 void InitiateExtensionSuspendedCleanup(const std::string& extension_id) { 269 void InitiateExtensionSuspendedCleanup(const std::string& extension_id) {
236 if (content::BrowserThread::CurrentlyOn(thread_id_)) { 270 if (ThreadingTraits::IsCalledOnValidThread()) {
237 CleanupResourcesFromSuspendedExtension(extension_id); 271 CleanupResourcesFromSuspendedExtension(extension_id);
238 } else { 272 } else {
239 content::BrowserThread::PostTask( 273 ThreadingTraits::GetSequencedTaskRunner()->PostTask(
240 thread_id_,
241 FROM_HERE, 274 FROM_HERE,
242 base::Bind(&ApiResourceData::CleanupResourcesFromSuspendedExtension, 275 base::Bind(&ApiResourceData::CleanupResourcesFromSuspendedExtension,
243 this, 276 this,
244 extension_id)); 277 extension_id));
245 } 278 }
246 } 279 }
247 280
248 void InititateCleanup() { 281 void InititateCleanup() {
249 if (content::BrowserThread::CurrentlyOn(thread_id_)) { 282 if (ThreadingTraits::IsCalledOnValidThread()) {
250 Cleanup(); 283 Cleanup();
251 } else { 284 } else {
252 content::BrowserThread::PostTask( 285 ThreadingTraits::GetSequencedTaskRunner()->PostTask(
253 thread_id_, FROM_HERE, base::Bind(&ApiResourceData::Cleanup, this)); 286 FROM_HERE, base::Bind(&ApiResourceData::Cleanup, this));
254 } 287 }
255 } 288 }
256 289
257 private: 290 private:
258 friend class base::RefCountedThreadSafe<ApiResourceData>; 291 friend class base::RefCountedThreadSafe<ApiResourceData>;
259 292
260 virtual ~ApiResourceData() {} 293 virtual ~ApiResourceData() {}
261 294
262 T* GetOwnedResource(const std::string& extension_id, int api_resource_id) { 295 T* GetOwnedResource(const std::string& extension_id, int api_resource_id) {
263 linked_ptr<T> ptr = api_resource_map_[api_resource_id]; 296 linked_ptr<T> ptr = api_resource_map_[api_resource_id];
264 T* resource = ptr.get(); 297 T* resource = ptr.get();
265 if (resource && extension_id == resource->owner_extension_id()) 298 if (resource && extension_id == resource->owner_extension_id())
266 return resource; 299 return resource;
267 return NULL; 300 return NULL;
268 } 301 }
269 302
270 base::hash_set<int>* GetOwnedResourceIds(const std::string& extension_id) { 303 base::hash_set<int>* GetOwnedResourceIds(const std::string& extension_id) {
271 DCHECK_CURRENTLY_ON(thread_id_); 304 DCHECK(ThreadingTraits::IsCalledOnValidThread());
272 if (extension_resource_map_.find(extension_id) == 305 if (extension_resource_map_.find(extension_id) ==
273 extension_resource_map_.end()) 306 extension_resource_map_.end())
274 return NULL; 307 return NULL;
275 308
276 return &extension_resource_map_[extension_id]; 309 return &extension_resource_map_[extension_id];
277 } 310 }
278 311
279 void CleanupResourcesFromUnloadedExtension( 312 void CleanupResourcesFromUnloadedExtension(
280 const std::string& extension_id) { 313 const std::string& extension_id) {
281 CleanupResourcesFromExtension(extension_id, true); 314 CleanupResourcesFromExtension(extension_id, true);
282 } 315 }
283 316
284 void CleanupResourcesFromSuspendedExtension( 317 void CleanupResourcesFromSuspendedExtension(
285 const std::string& extension_id) { 318 const std::string& extension_id) {
286 CleanupResourcesFromExtension(extension_id, false); 319 CleanupResourcesFromExtension(extension_id, false);
287 } 320 }
288 321
289 void CleanupResourcesFromExtension(const std::string& extension_id, 322 void CleanupResourcesFromExtension(const std::string& extension_id,
290 bool remove_all) { 323 bool remove_all) {
291 DCHECK_CURRENTLY_ON(thread_id_); 324 DCHECK(ThreadingTraits::IsCalledOnValidThread());
292 325
293 if (extension_resource_map_.find(extension_id) == 326 if (extension_resource_map_.find(extension_id) ==
294 extension_resource_map_.end()) { 327 extension_resource_map_.end()) {
295 return; 328 return;
296 } 329 }
297 330
298 // Remove all resources, or the non persistent ones only if |remove_all| 331 // Remove all resources, or the non persistent ones only if |remove_all|
299 // is false. 332 // is false.
300 base::hash_set<int>& resource_ids = extension_resource_map_[extension_id]; 333 base::hash_set<int>& resource_ids = extension_resource_map_[extension_id];
301 for (base::hash_set<int>::iterator it = resource_ids.begin(); 334 for (base::hash_set<int>::iterator it = resource_ids.begin();
(...skipping 15 matching lines...) Expand all
317 } 350 }
318 } // end for 351 } // end for
319 352
320 // Remove extension entry if we removed all its resources. 353 // Remove extension entry if we removed all its resources.
321 if (resource_ids.size() == 0) { 354 if (resource_ids.size() == 0) {
322 extension_resource_map_.erase(extension_id); 355 extension_resource_map_.erase(extension_id);
323 } 356 }
324 } 357 }
325 358
326 void Cleanup() { 359 void Cleanup() {
327 DCHECK_CURRENTLY_ON(thread_id_); 360 DCHECK(ThreadingTraits::IsCalledOnValidThread());
328 361
329 api_resource_map_.clear(); 362 api_resource_map_.clear();
330 extension_resource_map_.clear(); 363 extension_resource_map_.clear();
331 } 364 }
332 365
333 int GenerateId() { return next_id_++; } 366 int GenerateId() { return next_id_++; }
334 367
335 int next_id_; 368 int next_id_;
336 const content::BrowserThread::ID thread_id_;
337 ApiResourceMap api_resource_map_; 369 ApiResourceMap api_resource_map_;
338 ExtensionToResourceMap extension_resource_map_; 370 ExtensionToResourceMap extension_resource_map_;
339 }; 371 };
340 372
341 content::BrowserThread::ID thread_id_;
342 content::NotificationRegistrar registrar_; 373 content::NotificationRegistrar registrar_;
343 scoped_refptr<ApiResourceData> data_; 374 scoped_refptr<ApiResourceData> data_;
344 }; 375 };
345 376
377 // With WorkerPoolThreadTraits, ApiResourceManager can be used to manage the
378 // lifetime of a set of resources that live on sequenced task runner threads
379 // which ApiFunctions use. Examples of such resources are temporary file
380 // resources produced by certain API calls.
381 //
382 // Instead of kThreadId. classes used for tracking such resources should define
383 // kSequenceToken and kShutdownBehavior to identify sequence task runner for
384 // ApiResourceManager to work on and how pending tasks should behave on
385 // shutdown.
386 // The user must also define a static const char* service_name() that returns
387 // the name of the service, and in order for ApiWorkerPoolResourceManager to use
388 // service_name() friend this class.
389 //
390 // In the cc file the user must define a GetFactoryInstance() and manage their
391 // own instances (typically using LazyInstance or Singleton).
392 //
393 // E.g.:
394 //
395 // class PoolResource {
396 // public:
397 // static const char kSequenceToken[] = "temp_files";
398 // static const base::SequencedWorkerPool::WorkerShutdown kShutdownBehavior =
399 // base::SequencedWorkerPool::BLOCK_SHUTDOWN;
400 // private:
401 // friend class ApiResourceManager<WorkerPoolResource,
402 // WorkerPoolThreadTraits>;
403 // static const char* service_name() {
404 // return "TempFilesResourceManager";
405 // }
406 // };
407 //
408 // In the cc file:
409 //
410 // static base::LazyInstance<BrowserContextKeyedAPIFactory<
411 // ApiResourceManager<Resource, WorkerPoolThreadTraits> > >
412 // g_factory = LAZY_INSTANCE_INITIALIZER;
413 //
414 //
415 // template <>
416 // BrowserContextKeyedAPIFactory<ApiResourceManager<WorkerPoolResource> >*
417 // ApiResourceManager<WorkerPoolPoolResource,
418 // WorkerPoolThreadTraits>::GetFactoryInstance() {
419 // return g_factory.Pointer();
420 // }
421 template <typename T>
422 struct WorkerPoolThreadTraits {
423 static bool IsCalledOnValidThread() {
424 return content::BrowserThread::GetBlockingPool()
425 ->IsRunningSequenceOnCurrentThread(
426 content::BrowserThread::GetBlockingPool()->GetNamedSequenceToken(
427 T::kSequenceToken));
428 }
429
430 static bool IsMessageLoopValid() {
431 return content::BrowserThread::GetBlockingPool() != NULL;
432 }
433
434 static scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() {
435 return content::BrowserThread::GetBlockingPool()
436 ->GetSequencedTaskRunnerWithShutdownBehavior(
437 content::BrowserThread::GetBlockingPool()->GetNamedSequenceToken(
438 T::kSequenceToken),
439 T::kShutdownBehavior);
440 }
441 };
442
346 } // namespace extensions 443 } // namespace extensions
347 444
348 #endif // EXTENSIONS_BROWSER_API_API_RESOURCE_MANAGER_H_ 445 #endif // EXTENSIONS_BROWSER_API_API_RESOURCE_MANAGER_H_
OLDNEW
« no previous file with comments | « content/renderer/media/mock_peer_connection_impl.cc ('k') | extensions/browser/extension_function_histogram_value.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698