diff options
author | ikarienator@chromium.org <ikarienator@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-16 00:10:26 +0000 |
---|---|---|
committer | ikarienator@chromium.org <ikarienator@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-16 00:10:26 +0000 |
commit | 7ad4583b7894d77582bc4fda17f7d80dbd6eb84c (patch) | |
tree | 48784ad28e511cf75dfcea51ec7538ed50959c34 /chrome/browser/usb | |
parent | 467a185e5813c1b428d88188440251d9d4257203 (diff) | |
download | chromium_src-7ad4583b7894d77582bc4fda17f7d80dbd6eb84c.zip chromium_src-7ad4583b7894d77582bc4fda17f7d80dbd6eb84c.tar.gz chromium_src-7ad4583b7894d77582bc4fda17f7d80dbd6eb84c.tar.bz2 |
Provide a more elegant UsbService::GetInstance static method.
BUG=327392
Review URL: https://codereview.chromium.org/126713002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245025 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/usb')
-rw-r--r-- | chrome/browser/usb/usb_service.cc | 44 | ||||
-rw-r--r-- | chrome/browser/usb/usb_service.h | 3 |
2 files changed, 28 insertions, 19 deletions
diff --git a/chrome/browser/usb/usb_service.cc b/chrome/browser/usb/usb_service.cc index 15e6abf..221ccbb 100644 --- a/chrome/browser/usb/usb_service.cc +++ b/chrome/browser/usb/usb_service.cc @@ -35,9 +35,16 @@ using std::vector; namespace { +// This is the one and only instance of UsbService. The reason not to use +// Singleton is: 1. Singleton focuses on solving race conditions and at-exit +// deletion, none of them are needed here, and 2. Singleton does not provide +// a way to clear the pointer after the instance being destroyed. +UsbService* g_usb_service_instance = NULL; +bool g_usb_service_instance_destroyed = false; + class ExitObserver : public content::NotificationObserver { public: - explicit ExitObserver(UsbService* service) : service_(service) { + ExitObserver() { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&content::NotificationRegistrar::Add, @@ -52,49 +59,54 @@ class ExitObserver : public content::NotificationObserver { const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE { if (type == chrome::NOTIFICATION_APP_TERMINATING) { - BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, service_); + BrowserThread::DeleteSoon(BrowserThread::FILE, + FROM_HERE, + g_usb_service_instance); delete this; } } - UsbService* service_; content::NotificationRegistrar registrar_; }; } // namespace -using content::BrowserThread; - UsbService::UsbService(PlatformUsbContext context) : context_(new UsbContext(context)), next_unique_id_(0) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - // Will be deleted upon NOTIFICATION_APP_TERMINATING. - new ExitObserver(this); } UsbService::~UsbService() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + // Prevents creating a new UsbService. + g_usb_service_instance_destroyed = true; + g_usb_service_instance = NULL; + for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) { it->second->OnDisconnect(); } } -struct InitUsbContextTraits : public LeakySingletonTraits<UsbService> { - // LeakySingletonTraits<UsbService> - static UsbService* New() { +UsbService* UsbService::GetInstance() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + if (g_usb_service_instance_destroyed) + return NULL; + + if (!g_usb_service_instance) { PlatformUsbContext context = NULL; if (libusb_init(&context) != LIBUSB_SUCCESS) return NULL; if (!context) return NULL; - return new UsbService(context); + + g_usb_service_instance = new UsbService(context); + + // Will be deleted upon NOTIFICATION_APP_TERMINATING. + new ExitObserver(); } -}; -UsbService* UsbService::GetInstance() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - // UsbService deletes itself upon APP_TERMINATING. - return Singleton<UsbService, InitUsbContextTraits>::get(); + return g_usb_service_instance; } void UsbService::GetDevices(std::vector<scoped_refptr<UsbDevice> >* devices) { diff --git a/chrome/browser/usb/usb_service.h b/chrome/browser/usb/usb_service.h index ac8024c..55e7972 100644 --- a/chrome/browser/usb/usb_service.h +++ b/chrome/browser/usb/usb_service.h @@ -12,7 +12,6 @@ #include "base/basictypes.h" #include "base/callback.h" #include "base/memory/ref_counted.h" -#include "base/memory/singleton.h" namespace base { @@ -50,8 +49,6 @@ class UsbService { void GetDevices(std::vector<scoped_refptr<UsbDevice> >* devices); private: - friend struct InitUsbContextTraits; - friend struct DefaultSingletonTraits<UsbService>; friend class base::DeleteHelper<UsbService>; explicit UsbService(PlatformUsbContext context); |