| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_EXTENSIONS_API_API_RESOURCE_MANAGER_H_ |
| 6 #define CHROME_BROWSER_EXTENSIONS_API_API_RESOURCE_MANAGER_H_ |
| 7 |
| 8 #include <map> |
| 9 |
| 10 #include "base/memory/linked_ptr.h" |
| 11 #include "base/threading/non_thread_safe.h" |
| 12 #include "chrome/browser/profiles/profile_keyed_service.h" |
| 13 #include "content/public/browser/browser_thread.h" |
| 14 |
| 15 using content::BrowserThread; |
| 16 |
| 17 namespace extensions { |
| 18 |
| 19 // An ApiResourceManager manages the lifetime of a set of resources that |
| 20 // ApiFunctions use. Examples are sockets or USB connections. |
| 21 template <class T> |
| 22 class ApiResourceManager : public ProfileKeyedService, |
| 23 public base::NonThreadSafe { |
| 24 public: |
| 25 explicit ApiResourceManager(BrowserThread::ID thread_id) |
| 26 : next_id_(1), |
| 27 thread_id_(thread_id), |
| 28 api_resource_map_(new std::map<int, linked_ptr<T> >()) { |
| 29 } |
| 30 |
| 31 virtual ~ApiResourceManager() { |
| 32 DCHECK(CalledOnValidThread()); |
| 33 |
| 34 DCHECK(BrowserThread::IsMessageLoopValid(thread_id_)) << |
| 35 "A unit test is using an ApiResourceManager but didn't provide " |
| 36 "the thread message loop needed for that kind of resource. " |
| 37 "Please ensure that the appropriate message loop is operational."; |
| 38 |
| 39 BrowserThread::DeleteSoon(thread_id_, FROM_HERE, api_resource_map_); |
| 40 } |
| 41 |
| 42 // Takes ownership. |
| 43 int Add(T* api_resource) { |
| 44 DCHECK(BrowserThread::CurrentlyOn(thread_id_)); |
| 45 int id = GenerateId(); |
| 46 if (id > 0) { |
| 47 linked_ptr<T> resource_ptr(api_resource); |
| 48 (*api_resource_map_)[id] = resource_ptr; |
| 49 return id; |
| 50 } |
| 51 return 0; |
| 52 } |
| 53 |
| 54 void Remove(int api_resource_id) { |
| 55 DCHECK(BrowserThread::CurrentlyOn(thread_id_)); |
| 56 api_resource_map_->erase(api_resource_id); |
| 57 } |
| 58 |
| 59 T* Get(int api_resource_id) { |
| 60 DCHECK(BrowserThread::CurrentlyOn(thread_id_)); |
| 61 linked_ptr<T> ptr = (*api_resource_map_)[api_resource_id]; |
| 62 return ptr.get(); |
| 63 } |
| 64 |
| 65 private: |
| 66 // TODO(miket): consider partitioning the ID space by extension ID to make it |
| 67 // harder for extensions to peek into each others' resources. |
| 68 int GenerateId() { |
| 69 return next_id_++; |
| 70 } |
| 71 |
| 72 int next_id_; |
| 73 BrowserThread::ID thread_id_; |
| 74 |
| 75 // We need finer-grained control over the lifetime of this instance than RAII |
| 76 // can give us. |
| 77 std::map<int, linked_ptr<T> >* api_resource_map_; |
| 78 }; |
| 79 |
| 80 } // namespace extensions |
| 81 |
| 82 #endif // CHROME_BROWSER_EXTENSIONS_API_API_RESOURCE_MANAGER_H_ |
| OLD | NEW |