summaryrefslogtreecommitdiffstats
path: root/chrome/browser/usb
diff options
context:
space:
mode:
authorikarienator@chromium.org <ikarienator@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-16 00:10:26 +0000
committerikarienator@chromium.org <ikarienator@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-16 00:10:26 +0000
commit7ad4583b7894d77582bc4fda17f7d80dbd6eb84c (patch)
tree48784ad28e511cf75dfcea51ec7538ed50959c34 /chrome/browser/usb
parent467a185e5813c1b428d88188440251d9d4257203 (diff)
downloadchromium_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.cc44
-rw-r--r--chrome/browser/usb/usb_service.h3
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);