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 COMPONENTS_BROWSER_CONTEXT_KEYED_SERVICE_REFCOUNTED_BROWSER_CONTEXT_KEYED_SERVICE_H_ 6 #define COMPONENTS_BROWSER_CONTEXT_KEYED_SERVICE_REFCOUNTED_BROWSER_CONTEXT_KEYED_SERVICE_H_ 7 8 #include "base/memory/ref_counted.h" 9 #include "base/sequenced_task_runner_helpers.h" 10 #include "components/browser_context_keyed_service/browser_context_keyed_service_export.h" 11 #include "content/public/browser/browser_thread.h" 12 13 class RefcountedBrowserContextKeyedService; 14 15 namespace impl { 16 17 struct BROWSER_CONTEXT_KEYED_SERVICE_EXPORT 18 RefcountedBrowserContextKeyedServiceTraits { 19 static void Destruct(const RefcountedBrowserContextKeyedService* obj); 20 }; 21 22 } // namespace impl 23 24 // Base class for refcounted objects that hang off the BrowserContext. 25 // 26 // The two pass shutdown described in BrowserContextKeyedService works a bit 27 // differently because there could be outstanding references on other 28 // threads. ShutdownOnUIThread() will be called on the UI thread, and then the 29 // destructor will run when the last reference is dropped, which may or may not 30 // be after the corresponding BrowserContext has been destroyed. 31 // 32 // Optionally, if you initialize your service with the constructor that takes a 33 // thread ID, your service will be deleted on that thread. We can't use 34 // content::DeleteOnThread<> directly because 35 // RefcountedBrowserContextKeyedService must be one type that 36 // RefcountedBrowserContextKeyedServiceFactory can use. 37 class BROWSER_CONTEXT_KEYED_SERVICE_EXPORT RefcountedBrowserContextKeyedService 38 : public base::RefCountedThreadSafe< 39 RefcountedBrowserContextKeyedService, 40 impl::RefcountedBrowserContextKeyedServiceTraits> { 41 public: 42 // Unlike BrowserContextKeyedService, ShutdownOnUI is not optional. You must 43 // do something to drop references during the first pass Shutdown() because 44 // this is the only point where you are guaranteed that something is running 45 // on the UI thread. The PKSF framework will ensure that this is only called 46 // on the UI thread; you do not need to check for that yourself. 47 virtual void ShutdownOnUIThread() = 0; 48 49 protected: 50 // If your service does not need to be deleted on a specific thread, use the 51 // default constructor. 52 RefcountedBrowserContextKeyedService(); 53 54 // If you need your service to be deleted on a specific thread (for example, 55 // you're converting a service that used content::DeleteOnThread<IO>), then 56 // use this constructor with the ID of the thread. 57 explicit RefcountedBrowserContextKeyedService( 58 const content::BrowserThread::ID thread_id); 59 60 // The second pass destruction can happen anywhere unless you specify which 61 // thread this service must be destroyed on by using the second constructor. 62 virtual ~RefcountedBrowserContextKeyedService(); 63 64 private: 65 friend struct impl::RefcountedBrowserContextKeyedServiceTraits; 66 friend class base::DeleteHelper<RefcountedBrowserContextKeyedService>; 67 friend class base::RefCountedThreadSafe<RefcountedBrowserContextKeyedService, 68 impl::RefcountedBrowserContextKeyedServiceTraits>; 69 70 // Do we have to delete this object on a specific thread? 71 bool requires_destruction_on_thread_; 72 content::BrowserThread::ID thread_id_; 73 }; 74 75 #endif // COMPONENTS_BROWSER_CONTEXT_KEYED_SERVICE_REFCOUNTED_BROWSER_CONTEXT_KEYED_SERVICE_H_ 76