Home | History | Annotate | Download | only in bluetooth
      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