1 // Copyright 2014 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 #include "device/bluetooth/bluetooth_socket_thread.h" 6 7 #include "base/lazy_instance.h" 8 #include "base/sequenced_task_runner.h" 9 #include "base/threading/thread.h" 10 11 namespace device { 12 13 base::LazyInstance<scoped_refptr<BluetoothSocketThread> > g_instance = 14 LAZY_INSTANCE_INITIALIZER; 15 16 // static 17 scoped_refptr<BluetoothSocketThread> BluetoothSocketThread::Get() { 18 if (!g_instance.Get().get()) { 19 g_instance.Get() = new BluetoothSocketThread(); 20 } 21 return g_instance.Get(); 22 } 23 24 // static 25 void BluetoothSocketThread::CleanupForTesting() { 26 DCHECK(g_instance.Get().get()); 27 g_instance.Get() = NULL; 28 } 29 30 BluetoothSocketThread::BluetoothSocketThread() 31 : active_socket_count_(0) {} 32 33 BluetoothSocketThread::~BluetoothSocketThread() { 34 if (thread_) { 35 thread_->Stop(); 36 thread_.reset(NULL); 37 task_runner_ = NULL; 38 } 39 } 40 41 void BluetoothSocketThread::OnSocketActivate() { 42 DCHECK(thread_checker_.CalledOnValidThread()); 43 active_socket_count_++; 44 EnsureStarted(); 45 } 46 47 void BluetoothSocketThread::OnSocketDeactivate() { 48 DCHECK(thread_checker_.CalledOnValidThread()); 49 active_socket_count_--; 50 if (active_socket_count_ == 0 && thread_) { 51 thread_->Stop(); 52 thread_.reset(NULL); 53 task_runner_ = NULL; 54 } 55 } 56 57 void BluetoothSocketThread::EnsureStarted() { 58 DCHECK(thread_checker_.CalledOnValidThread()); 59 if (thread_) 60 return; 61 62 base::Thread::Options thread_options; 63 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; 64 thread_.reset(new base::Thread("BluetoothSocketThread")); 65 thread_->StartWithOptions(thread_options); 66 task_runner_ = thread_->message_loop_proxy(); 67 } 68 69 scoped_refptr<base::SequencedTaskRunner> BluetoothSocketThread::task_runner() 70 const { 71 DCHECK(active_socket_count_ > 0); 72 DCHECK(thread_); 73 DCHECK(task_runner_.get()); 74 75 return task_runner_; 76 } 77 78 } // namespace device 79