| Index: device/usb/usb_context.cc
|
| diff --git a/device/usb/usb_context.cc b/device/usb/usb_context.cc
|
| index cb8214fedb135876bffe2e1ec4aec03e4130e736..7661469d294911994d8fb4b83332fb6fe267b2af 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
|
|
|