diff options
Diffstat (limited to 'device/usb/usb_context.cc')
-rw-r--r-- | device/usb/usb_context.cc | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/device/usb/usb_context.cc b/device/usb/usb_context.cc index cb8214f..7661469 100644 --- a/device/usb/usb_context.cc +++ b/device/usb/usb_context.cc @@ -6,7 +6,6 @@ #include "base/atomicops.h" #include "base/logging.h" -#include "base/synchronization/waitable_event.h" #include "base/threading/platform_thread.h" #include "device/usb/usb_error.h" #include "third_party/libusb/src/libusb/interrupt.h" @@ -25,35 +24,30 @@ class UsbContext::UsbEventHandler : public base::PlatformThread::Delegate { // base::PlatformThread::Delegate void ThreadMain() override; + void Stop(); + private: base::subtle::Atomic32 running_; libusb_context* context_; base::PlatformThreadHandle thread_handle_; - base::WaitableEvent start_polling_; DISALLOW_COPY_AND_ASSIGN(UsbEventHandler); }; UsbContext::UsbEventHandler::UsbEventHandler(libusb_context* context) - : context_(context), thread_handle_(0), start_polling_(false, false) { + : context_(context), thread_handle_(0) { base::subtle::Release_Store(&running_, 1); bool success = base::PlatformThread::Create(0, this, &thread_handle_); DCHECK(success) << "Failed to create USB IO handling thread."; - start_polling_.Wait(); } UsbContext::UsbEventHandler::~UsbEventHandler() { - base::subtle::Release_Store(&running_, 0); - libusb_interrupt_handle_event(context_); - base::PlatformThread::Join(thread_handle_); + libusb_exit(context_); } void UsbContext::UsbEventHandler::ThreadMain() { base::PlatformThread::SetName("UsbEventHandler"); VLOG(1) << "UsbEventHandler started."; - if (base::subtle::Acquire_Load(&running_)) { - start_polling_.Signal(); - } while (base::subtle::Acquire_Load(&running_)) { const int rv = libusb_handle_events(context_); if (rv != LIBUSB_SUCCESS) { @@ -61,20 +55,24 @@ void UsbContext::UsbEventHandler::ThreadMain() { << ConvertPlatformUsbErrorToString(rv); } } + VLOG(1) << "UsbEventHandler shutting down."; + delete this; +} + +void UsbContext::UsbEventHandler::Stop() { + base::subtle::Release_Store(&running_, 0); + libusb_interrupt_handle_event(context_); } UsbContext::UsbContext(PlatformUsbContext context) : context_(context) { - DCHECK(thread_checker_.CalledOnValidThread()); + // Ownership of the PlatformUsbContext is passed to the event handler thread. event_handler_ = new UsbEventHandler(context_); } UsbContext::~UsbContext() { - // destruction of UsbEventHandler is a blocking operation. DCHECK(thread_checker_.CalledOnValidThread()); - delete event_handler_; - event_handler_ = NULL; - libusb_exit(context_); + event_handler_->Stop(); } } // namespace device |