线程异常管理;清空设备队列防止二次释放

This commit is contained in:
gb 2023-11-24 15:38:28 +08:00
parent 9347a4b752
commit f045f7187c
2 changed files with 37 additions and 21 deletions

View File

@ -18,14 +18,14 @@
#pragma comment(lib, "rpcrt4.lib")
#pragma comment(lib, "advapi32.lib") // for Reg...
#if defined(OEM_NONE) || defined(OEM_LISCHENG) || defined(OEM_HANWANG)|| defined(OEM_ZHONGJING)
#include "../wrapper/hg_log.h"
#else
#define VLOG_MINI_1(l, f, d) printf(f, d)
#define VLOG_MINI_2(l, f, d1, d2) printf(f, d1, d2)
#define VLOG_MINI_3(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)
#endif
//#if defined(OEM_NONE) || defined(OEM_LISCHENG) || defined(OEM_HANWANG)|| defined(OEM_ZHONGJING)
//#include "../wrapper/hg_log.h"
//#else
//#define utils::to_log(l, f, d) printf(f, d)
//#define utils::to_log(l, f, d1, d2) printf(f, d1, d2)
//#define utils::to_log(l, f, d1, d2, d3) printf(f, d1, d2, d3)
//#define utils::to_log(l, f, d1, d2, d3, d4) printf(f, d1, d2, d3, d4)
//#endif
#include "usbview/enum.h"
#include "../../../sdk/include/huagao/brand.h"
#include <base/utils.h>
@ -158,7 +158,7 @@ void ovl_mgr::notify_all(void)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// usb_device ...
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_));
}
@ -353,7 +353,7 @@ bool usb_device::init(void)
clear();
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())
{
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一个异常
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;
fmt = "\\%04d";
}
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());
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;
if (ret == ERROR_NO_MORE_ITEMS)
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
ret = LIBUSB_SUCCESS;
@ -685,11 +685,11 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
{
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
{
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;
}
@ -785,7 +785,7 @@ int usb_device::transfer_interrupt(unsigned endpoint, unsigned char* data, int*
}
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;
}
}
@ -814,7 +814,15 @@ UINT usb_monitor::find_usb_timer_ = 101;
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));
#endif
}
usb_monitor::~usb_monitor()
{
@ -986,7 +994,7 @@ void usb_monitor::notify_usb_event(usb_device*& dev, bool arrive)
{
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();
return;
}
@ -1035,7 +1043,7 @@ void usb_monitor::notify_usb_event(usb_device*& dev, bool arrive)
}
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;
}
}
@ -1061,7 +1069,7 @@ int usb_monitor::on_usb_pnp(WPARAM wp, LPARAM lp)
if (wp == DBT_DEVICEQUERYREMOVE)
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,
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);
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);
@ -1180,7 +1188,7 @@ void usb_monitor::thread_run_device_event_wnd(void)
di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
UuidFromStringA((RPC_CSTR)IMAGE_CLASS_GUID, &di.dbcc_classguid);
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)
SetTimer(wnd_monitor_, usb_monitor::find_usb_timer_, 1000, NULL);
}
@ -1228,6 +1236,7 @@ void usb_monitor::quit(void)
Sleep(100);
}
#ifndef USE_SAFE_THREAD
if (handle_msg_.get())
{
PostThreadMessageW(handle_msg_id_, WM_QUIT, 0, 0);
@ -1235,11 +1244,13 @@ void usb_monitor::quit(void)
handle_msg_->join();
handle_msg_.reset();
}
#endif
{
std::lock_guard<std::mutex> lock(lock_);
for (auto& v : devices_)
v->release();
devices_.clear();
}
}

View File

@ -13,6 +13,7 @@
#include <functional>
#include <memory>
#include "libusb-1.0/libusb.h"
#include <base/utils.h>
// 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::mutex lock_;
std::vector<usb_device*> devices_;
#ifdef USE_SAFE_THREAD
safe_thread handle_msg_;
#else
std::shared_ptr<std::thread> handle_msg_;
#endif
DWORD handle_msg_id_;
HWND wnd_monitor_;
std::string cur_dev_name_;