线程异常管理;清空设备队列防止二次释放
This commit is contained in:
parent
9347a4b752
commit
f045f7187c
|
@ -18,14 +18,14 @@
|
||||||
#pragma comment(lib, "rpcrt4.lib")
|
#pragma comment(lib, "rpcrt4.lib")
|
||||||
#pragma comment(lib, "advapi32.lib") // for Reg...
|
#pragma comment(lib, "advapi32.lib") // for Reg...
|
||||||
|
|
||||||
#if defined(OEM_NONE) || defined(OEM_LISCHENG) || defined(OEM_HANWANG)|| defined(OEM_ZHONGJING)
|
//#if defined(OEM_NONE) || defined(OEM_LISCHENG) || defined(OEM_HANWANG)|| defined(OEM_ZHONGJING)
|
||||||
#include "../wrapper/hg_log.h"
|
//#include "../wrapper/hg_log.h"
|
||||||
#else
|
//#else
|
||||||
#define VLOG_MINI_1(l, f, d) printf(f, d)
|
//#define utils::to_log(l, f, d) printf(f, d)
|
||||||
#define VLOG_MINI_2(l, f, d1, d2) printf(f, d1, d2)
|
//#define utils::to_log(l, f, d1, d2) printf(f, d1, d2)
|
||||||
#define VLOG_MINI_3(l, f, d1, d2, d3) printf(f, d1, d2, d3)
|
//#define utils::to_log(l, f, d1, d2, d3) printf(f, d1, d2, d3)
|
||||||
#define VLOG_MINI_4(l, f, d1, d2, d3, d4) printf(f, d1, d2, d3, d4)
|
//#define utils::to_log(l, f, d1, d2, d3, d4) printf(f, d1, d2, d3, d4)
|
||||||
#endif
|
//#endif
|
||||||
#include "usbview/enum.h"
|
#include "usbview/enum.h"
|
||||||
#include "../../../sdk/include/huagao/brand.h"
|
#include "../../../sdk/include/huagao/brand.h"
|
||||||
#include <base/utils.h>
|
#include <base/utils.h>
|
||||||
|
@ -158,7 +158,7 @@ void ovl_mgr::notify_all(void)
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// usb_device ...
|
// usb_device ...
|
||||||
usb_device::usb_device(const USBDEV& dev) : ref_(1), udev_(dev), is_ok_(false)
|
usb_device::usb_device(const USBDEV& dev) : ref_(1), udev_(dev), is_ok_(false)
|
||||||
, dev_desc_(NULL), handle_(NULL), online_(true), timout_ms_(1000)
|
, dev_desc_(NULL), handle_(NULL), online_(true), timout_ms_(0)
|
||||||
{
|
{
|
||||||
memset(&guid_, 0, sizeof(guid_));
|
memset(&guid_, 0, sizeof(guid_));
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,7 @@ bool usb_device::init(void)
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
usb_monitor::enum_usb_device(&usb_monitor::find_parent_hub, &udev_, true);
|
usb_monitor::enum_usb_device(&usb_monitor::find_parent_hub, &udev_, true);
|
||||||
VLOG_MINI_3(LOG_LEVEL_ALL, "Device '%s' at hub '%s + %d'\r\n", udev_.name.c_str(), udev_.hub.c_str(), udev_.port);
|
utils::to_log(LOG_LEVEL_ALL, "Device '%s' at hub '%s + %d'\r\n", udev_.name.c_str(), udev_.hub.c_str(), udev_.port);
|
||||||
if (!udev_.hub.empty())
|
if (!udev_.hub.empty())
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA(udev_.hub.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
HANDLE h = CreateFileA(udev_.hub.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
@ -553,13 +553,13 @@ int usb_device::open(libusb_device_handle** dev_handle)
|
||||||
root = usb_device::usb_scan_name(udev_.driver_key.c_str());//name使用root时会导致 IO一个异常
|
root = usb_device::usb_scan_name(udev_.driver_key.c_str());//name使用root时会导致 IO一个异常
|
||||||
if (root.empty())
|
if (root.empty())
|
||||||
{
|
{
|
||||||
VLOG_MINI_1(LOG_LEVEL_WARNING, "Cannot find '\\\\.\\Usbscan' name for '%s', try run in Administrator!\r\n", udev_.name.c_str());
|
utils::to_log(LOG_LEVEL_WARNING, "Cannot find '\\\\.\\Usbscan' name for '%s', try run in Administrator!\r\n", udev_.name.c_str());
|
||||||
root = udev_.name;
|
root = udev_.name;
|
||||||
fmt = "\\%04d";
|
fmt = "\\%04d";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VLOG_MINI_2(LOG_LEVEL_WARNING, "Nice: '%s' for '%s'.\r\n", root.c_str(), udev_.name.c_str());
|
utils::to_log(LOG_LEVEL_WARNING, "Nice: '%s' for '%s'.\r\n", root.c_str(), udev_.name.c_str());
|
||||||
}
|
}
|
||||||
h = open_usb(udev_.name.c_str());
|
h = open_usb(udev_.name.c_str());
|
||||||
if (h == INVALID_HANDLE_VALUE)
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
|
@ -673,7 +673,7 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
|
||||||
ret = oc->over_lapped()->Internal == STATUS_CANCELLED ? /*LIBUSB_ERROR_TRY_AGAIN*/LIBUSB_ERROR_INTERRUPTED : oc->over_lapped()->Internal;
|
ret = oc->over_lapped()->Internal == STATUS_CANCELLED ? /*LIBUSB_ERROR_TRY_AGAIN*/LIBUSB_ERROR_INTERRUPTED : oc->over_lapped()->Internal;
|
||||||
if (ret == ERROR_NO_MORE_ITEMS)
|
if (ret == ERROR_NO_MORE_ITEMS)
|
||||||
ret = LIBUSB_ERROR_TIMEOUT;
|
ret = LIBUSB_ERROR_TIMEOUT;
|
||||||
VLOG_MINI_2(LOG_LEVEL_WARNING, "Bulk-Transfer of endpoint 0x%02x failed with code 0x%08X\n", endpoint, oc->over_lapped()->Internal);
|
utils::to_log(LOG_LEVEL_WARNING, "Bulk-Transfer of endpoint 0x%02x failed with code 0x%08X\n", endpoint, oc->over_lapped()->Internal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = LIBUSB_SUCCESS;
|
ret = LIBUSB_SUCCESS;
|
||||||
|
@ -685,11 +685,11 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
|
||||||
{
|
{
|
||||||
if (endpoint & BULKIN_FLAG)
|
if (endpoint & BULKIN_FLAG)
|
||||||
{
|
{
|
||||||
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Read-bulk = %d, set error as LIBUSB_ERROR_PIPE\r\n", io);
|
utils::to_log(LOG_LEVEL_DEBUG, "Read-bulk = %d, set error as LIBUSB_ERROR_PIPE\r\n", io);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Write-bulk = %d, set error as LIBUSB_ERROR_PIPE\r\n", io);
|
utils::to_log(LOG_LEVEL_DEBUG, "Write-bulk = %d, set error as LIBUSB_ERROR_PIPE\r\n", io);
|
||||||
}
|
}
|
||||||
ret = LIBUSB_ERROR_PIPE;
|
ret = LIBUSB_ERROR_PIPE;
|
||||||
}
|
}
|
||||||
|
@ -785,7 +785,7 @@ int usb_device::transfer_interrupt(unsigned endpoint, unsigned char* data, int*
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "DeviceIoControl(INT-EP) = %d, set error as LIBUSB_ERROR_PIPE\r\n", io);
|
utils::to_log(LOG_LEVEL_DEBUG, "DeviceIoControl(INT-EP) = %d, set error as LIBUSB_ERROR_PIPE\r\n", io);
|
||||||
ret = LIBUSB_ERROR_PIPE;
|
ret = LIBUSB_ERROR_PIPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -814,7 +814,15 @@ UINT usb_monitor::find_usb_timer_ = 101;
|
||||||
|
|
||||||
usb_monitor::usb_monitor() : wnd_monitor_(NULL), handle_msg_id_(0), run_(true)
|
usb_monitor::usb_monitor() : wnd_monitor_(NULL), handle_msg_id_(0), run_(true)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_SAFE_THREAD
|
||||||
|
auto tf = [this](void*) -> void
|
||||||
|
{
|
||||||
|
thread_handle_device_change_msg();
|
||||||
|
};
|
||||||
|
handle_msg_.start(tf, nullptr, "usb_monitor::thread_handle_device_change_msg");
|
||||||
|
#else
|
||||||
handle_msg_.reset(new std::thread(&usb_monitor::thread_handle_device_change_msg, this));
|
handle_msg_.reset(new std::thread(&usb_monitor::thread_handle_device_change_msg, this));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
usb_monitor::~usb_monitor()
|
usb_monitor::~usb_monitor()
|
||||||
{
|
{
|
||||||
|
@ -986,7 +994,7 @@ void usb_monitor::notify_usb_event(usb_device*& dev, bool arrive)
|
||||||
{
|
{
|
||||||
if (devices_[i]->is_online())
|
if (devices_[i]->is_online())
|
||||||
{
|
{
|
||||||
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "%s is already in device queue and received ARRIVE again, discard this event.\n", dev->name().c_str());
|
utils::to_log(LOG_LEVEL_DEBUG, "%s is already in device queue and received ARRIVE again, discard this event.\n", dev->name().c_str());
|
||||||
// dev->release();
|
// dev->release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1035,7 +1043,7 @@ void usb_monitor::notify_usb_event(usb_device*& dev, bool arrive)
|
||||||
}
|
}
|
||||||
if (discard)
|
if (discard)
|
||||||
{
|
{
|
||||||
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "%s is already offline and received LEAVE again, discard this event.\n", dev->name().c_str());
|
utils::to_log(LOG_LEVEL_DEBUG, "%s is already offline and received LEAVE again, discard this event.\n", dev->name().c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1061,7 +1069,7 @@ int usb_monitor::on_usb_pnp(WPARAM wp, LPARAM lp)
|
||||||
if (wp == DBT_DEVICEQUERYREMOVE)
|
if (wp == DBT_DEVICEQUERYREMOVE)
|
||||||
return cur_dev_name_ != utf8;
|
return cur_dev_name_ != utf8;
|
||||||
|
|
||||||
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "event '%08x' of device %s\n", wp, utf8.c_str());
|
utils::to_log(LOG_LEVEL_DEBUG, "event '%08x' of device %s\n", wp, utf8.c_str());
|
||||||
|
|
||||||
int vid = 0,
|
int vid = 0,
|
||||||
pid = 0;
|
pid = 0;
|
||||||
|
@ -1074,7 +1082,7 @@ int usb_monitor::on_usb_pnp(WPARAM wp, LPARAM lp)
|
||||||
usb_monitor::enum_usb_device(&usb_monitor::usb_dev_by_name, &udev);
|
usb_monitor::enum_usb_device(&usb_monitor::usb_dev_by_name, &udev);
|
||||||
if (wp == DBT_DEVICEARRIVAL && udev.driver_key.empty())
|
if (wp == DBT_DEVICEARRIVAL && udev.driver_key.empty())
|
||||||
{
|
{
|
||||||
VLOG_MINI_1(LOG_LEVEL_FATAL, "Failed: driver key for '%s' is not found!\r\n", utf8.c_str());
|
utils::to_log(LOG_LEVEL_FATAL, "Failed: driver key for '%s' is not found!\r\n", utf8.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_device* ud = new usb_device(udev);
|
usb_device* ud = new usb_device(udev);
|
||||||
|
@ -1180,7 +1188,7 @@ void usb_monitor::thread_run_device_event_wnd(void)
|
||||||
di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||||
UuidFromStringA((RPC_CSTR)IMAGE_CLASS_GUID, &di.dbcc_classguid);
|
UuidFromStringA((RPC_CSTR)IMAGE_CLASS_GUID, &di.dbcc_classguid);
|
||||||
notify = RegisterDeviceNotificationA(wnd_monitor_, &di, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
|
notify = RegisterDeviceNotificationA(wnd_monitor_, &di, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
|
||||||
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "RegisterDeviceNotificationA = 0x%08x, error = %d. di.dbcc_size = %d\n", notify, GetLastError(), di.dbcc_size);
|
utils::to_log(LOG_LEVEL_DEBUG, "RegisterDeviceNotificationA = 0x%08x, error = %d. di.dbcc_size = %d\n", notify, GetLastError(), di.dbcc_size);
|
||||||
if (!notify)
|
if (!notify)
|
||||||
SetTimer(wnd_monitor_, usb_monitor::find_usb_timer_, 1000, NULL);
|
SetTimer(wnd_monitor_, usb_monitor::find_usb_timer_, 1000, NULL);
|
||||||
}
|
}
|
||||||
|
@ -1228,6 +1236,7 @@ void usb_monitor::quit(void)
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_SAFE_THREAD
|
||||||
if (handle_msg_.get())
|
if (handle_msg_.get())
|
||||||
{
|
{
|
||||||
PostThreadMessageW(handle_msg_id_, WM_QUIT, 0, 0);
|
PostThreadMessageW(handle_msg_id_, WM_QUIT, 0, 0);
|
||||||
|
@ -1235,11 +1244,13 @@ void usb_monitor::quit(void)
|
||||||
handle_msg_->join();
|
handle_msg_->join();
|
||||||
handle_msg_.reset();
|
handle_msg_.reset();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(lock_);
|
std::lock_guard<std::mutex> lock(lock_);
|
||||||
for (auto& v : devices_)
|
for (auto& v : devices_)
|
||||||
v->release();
|
v->release();
|
||||||
|
devices_.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "libusb-1.0/libusb.h"
|
#include "libusb-1.0/libusb.h"
|
||||||
|
#include <base/utils.h>
|
||||||
|
|
||||||
|
|
||||||
// HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092f}
|
// HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092f}
|
||||||
|
@ -178,7 +179,11 @@ class usb_monitor // consider as libusb_context
|
||||||
std::vector<usb_callback*> cbs_;
|
std::vector<usb_callback*> cbs_;
|
||||||
std::mutex lock_;
|
std::mutex lock_;
|
||||||
std::vector<usb_device*> devices_;
|
std::vector<usb_device*> devices_;
|
||||||
|
#ifdef USE_SAFE_THREAD
|
||||||
|
safe_thread handle_msg_;
|
||||||
|
#else
|
||||||
std::shared_ptr<std::thread> handle_msg_;
|
std::shared_ptr<std::thread> handle_msg_;
|
||||||
|
#endif
|
||||||
DWORD handle_msg_id_;
|
DWORD handle_msg_id_;
|
||||||
HWND wnd_monitor_;
|
HWND wnd_monitor_;
|
||||||
std::string cur_dev_name_;
|
std::string cur_dev_name_;
|
||||||
|
|
Loading…
Reference in New Issue