| Index: content/browser/gamepad/gamepad_provider.cc
|
| diff --git a/content/browser/gamepad/gamepad_provider.cc b/content/browser/gamepad/gamepad_provider.cc
|
| index c8eed65a30f00b447a888bfa75eedf7932c9f521..c16245b32c9b82e9c35d3b0b48b90fb955d53e92 100644
|
| --- a/content/browser/gamepad/gamepad_provider.cc
|
| +++ b/content/browser/gamepad/gamepad_provider.cc
|
| @@ -23,8 +23,6 @@
|
|
|
| namespace content {
|
|
|
| -GamepadProvider* GamepadProvider::instance_ = NULL;
|
| -
|
| // Define the default data fetcher that GamepadProvider will use if none is
|
| // supplied. (GamepadPlatformDataFetcher).
|
| #if defined(OS_WIN)
|
| @@ -44,9 +42,9 @@ typedef GamepadEmptyDataFetcher GamepadPlatformDataFetcher;
|
| #endif
|
|
|
| GamepadProvider::GamepadProvider(GamepadDataFetcher* fetcher)
|
| - : creator_loop_(MessageLoop::current()->message_loop_proxy()),
|
| - provided_fetcher_(fetcher),
|
| + : is_paused_(false),
|
| devices_changed_(true),
|
| + provided_fetcher_(fetcher),
|
| ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
| size_t data_size = sizeof(GamepadHardwareBuffer);
|
| base::SystemMonitor* monitor = base::SystemMonitor::Get();
|
| @@ -55,13 +53,23 @@ GamepadProvider::GamepadProvider(GamepadDataFetcher* fetcher)
|
| gamepad_shared_memory_.CreateAndMapAnonymous(data_size);
|
| GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer();
|
| memset(hwbuf, 0, sizeof(GamepadHardwareBuffer));
|
| +
|
| + polling_thread_.reset(new base::Thread("Gamepad polling thread"));
|
| + polling_thread_->Start();
|
| +
|
| + MessageLoop* polling_loop = polling_thread_->message_loop();
|
| + polling_loop->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&GamepadProvider::DoInitializePollingThread, this));
|
| }
|
|
|
| GamepadProvider::~GamepadProvider() {
|
| base::SystemMonitor* monitor = base::SystemMonitor::Get();
|
| if (monitor)
|
| monitor->RemoveDevicesChangedObserver(this);
|
| - Stop();
|
| +
|
| + polling_thread_.reset();
|
| + data_fetcher_.reset();
|
| }
|
|
|
| base::SharedMemoryHandle GamepadProvider::GetRendererSharedMemoryHandle(
|
| @@ -71,34 +79,28 @@ base::SharedMemoryHandle GamepadProvider::GetRendererSharedMemoryHandle(
|
| return renderer_handle;
|
| }
|
|
|
| -void GamepadProvider::OnDevicesChanged() {
|
| - devices_changed_ = true;
|
| +void GamepadProvider::Pause() {
|
| + base::AutoLock lock(is_paused_lock_);
|
| + is_paused_ = true;
|
| }
|
|
|
| -void GamepadProvider::Start() {
|
| - DCHECK(MessageLoop::current()->message_loop_proxy() == creator_loop_);
|
| -
|
| - if (polling_thread_.get())
|
| - return;
|
| -
|
| - polling_thread_.reset(new base::Thread("Gamepad polling thread"));
|
| - if (!polling_thread_->Start()) {
|
| - LOG(ERROR) << "Failed to start gamepad polling thread";
|
| - polling_thread_.reset();
|
| - return;
|
| +void GamepadProvider::Resume() {
|
| + {
|
| + base::AutoLock lock(is_paused_lock_);
|
| + if (!is_paused_)
|
| + return;
|
| + is_paused_ = false;
|
| }
|
|
|
| MessageLoop* polling_loop = polling_thread_->message_loop();
|
| polling_loop->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&GamepadProvider::DoInitializePollingThread, this));
|
| + base::Bind(&GamepadProvider::ScheduleDoPoll, this));
|
| }
|
|
|
| -void GamepadProvider::Stop() {
|
| - DCHECK(MessageLoop::current()->message_loop_proxy() == creator_loop_);
|
| -
|
| - polling_thread_.reset();
|
| - data_fetcher_.reset();
|
| +void GamepadProvider::OnDevicesChanged() {
|
| + base::AutoLock lock(devices_changed_lock_);
|
| + devices_changed_ = true;
|
| }
|
|
|
| void GamepadProvider::DoInitializePollingThread() {
|
| @@ -116,6 +118,7 @@ void GamepadProvider::DoInitializePollingThread() {
|
|
|
| void GamepadProvider::DoPoll() {
|
| DCHECK(MessageLoop::current() == polling_thread_->message_loop());
|
| + bool changed;
|
| GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer();
|
|
|
| ANNOTATE_BENIGN_RACE_SIZED(
|
| @@ -123,12 +126,18 @@ void GamepadProvider::DoPoll() {
|
| sizeof(WebKit::WebGamepads),
|
| "Racey reads are discarded");
|
|
|
| + {
|
| + base::AutoLock lock(devices_changed_lock_);
|
| + changed = devices_changed_;
|
| + devices_changed_ = false;
|
| + }
|
| +
|
| // Acquire the SeqLock. There is only ever one writer to this data.
|
| // See gamepad_hardware_buffer.h.
|
| hwbuf->sequence.WriteBegin();
|
| - data_fetcher_->GetGamepadData(&hwbuf->buffer, devices_changed_);
|
| + data_fetcher_->GetGamepadData(&hwbuf->buffer, changed);
|
| hwbuf->sequence.WriteEnd();
|
| - devices_changed_ = false;
|
| +
|
| // Schedule our next interval of polling.
|
| ScheduleDoPoll();
|
| }
|
| @@ -136,6 +145,12 @@ void GamepadProvider::DoPoll() {
|
| void GamepadProvider::ScheduleDoPoll() {
|
| DCHECK(MessageLoop::current() == polling_thread_->message_loop());
|
|
|
| + {
|
| + base::AutoLock lock(is_paused_lock_);
|
| + if (is_paused_)
|
| + return;
|
| + }
|
| +
|
| MessageLoop::current()->PostDelayedTask(
|
| FROM_HERE,
|
| base::Bind(&GamepadProvider::DoPoll, weak_factory_.GetWeakPtr()),
|
|
|