改进热插拔重连判断机制

This commit is contained in:
gb 2022-07-04 16:30:01 +08:00
parent e4d5933b7f
commit 627b026b87
3 changed files with 44 additions and 25 deletions

View File

@ -168,37 +168,29 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
if (index != -1) if (index != -1)
{ {
bool add = true; bool add = true;
for (size_t i = 0; i < online_devices_.size(); ++i) size_t i = 0;
for (; i < online_devices_.size(); ++i)
{ {
if (online_devices_[i].dev == device) if (online_devices_[i].dev == device) // 此处假定同一台设备重新连接后设备对象“device”保持不变如果假设不成立会导致设备重连消息不能正常接收绑定到该设备的scanner对象得不到释放
{ {
online_devices_[i].ind = index; online_devices_[i].ind = index;
add = false; add = false;
break; break;
} }
else if (online_devices_[i].scanner && !online_devices_[i].scanner->is_online()
&& online_devices_[i].scanner->get_pid() == pid && online_devices_[i].scanner->get_vid() == vid)
{
usb_io* io = NULL;
name = online_devices_[i].display_name;
type = g_supporting_devices[index].type;
online_devices_[i].dev = device;
h = online_devices_[i].scanner;
if (pid == 0x300 || pid == 0x400)
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
len = usb_manager::instance()->open(device, &io);
if (len == SCANNER_ERR_OK)
{
VLOG_MINI_3(LOG_LEVEL_WARNING, "[%04x:%04x]%s re-connected.\n", pid, vid, online_devices_[i].display_name.c_str());
online_devices_[i].scanner->reset_io(io);
de.openned = SANE_TRUE;
} }
if (io) if (add) // 处理对象“device”改变的情景
io->release(); {
i = 0;
for (auto& v : online_devices_)
{
if (v.ind == index &&
(v.scanner == NULL || !v.scanner->is_online()))
{
add = false; add = false;
break; break;
} }
i++;
}
} }
if (add) if (add)
@ -216,10 +208,35 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
sprintf(buf, " - %u", same_ind_++); sprintf(buf, " - %u", same_ind_++);
ols.display_name += buf; ols.display_name += buf;
} }
libusb_ref_device(ols.dev); // ref to the device of queue online_devices_
online_devices_.push_back(ols); online_devices_.push_back(ols);
name = ols.display_name; name = ols.display_name;
type = g_supporting_devices[ols.ind].type; type = g_supporting_devices[ols.ind].type;
} }
else if (online_devices_[i].scanner && !online_devices_[i].scanner->is_online())
{
usb_io* io = NULL;
name = online_devices_[i].display_name;
type = g_supporting_devices[index].type;
if (online_devices_[i].dev)
libusb_unref_device(online_devices_[i].dev);
online_devices_[i].dev = device;
libusb_ref_device(online_devices_[i].dev);
h = online_devices_[i].scanner;
if (pid == 0x300 || pid == 0x400)
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
len = usb_manager::instance()->open(device, &io);
if (len == SCANNER_ERR_OK)
{
VLOG_MINI_3(LOG_LEVEL_WARNING, "[%04x:%04x]%s re-connected.\n", pid, vid, online_devices_[i].display_name.c_str());
online_devices_[i].scanner->reset_io(io);
de.openned = SANE_TRUE;
}
if (io)
io->release();
add = false;
}
} }
} }
else if (ev == USB_EVENT_DEVICE_LEFT) else if (ev == USB_EVENT_DEVICE_LEFT)
@ -235,9 +252,12 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
if (it->scanner) if (it->scanner)
it->scanner->io_disconnected(); it->scanner->io_disconnected();
else else
{
libusb_unref_device(it->dev); // unref the device of queue online_devices_
online_devices_.erase(it); online_devices_.erase(it);
} }
} }
}
if (ev_ui) if (ev_ui)
{ {

View File

@ -72,7 +72,7 @@ int LIBUSB_CALL usb_manager::usb_pnp_callback(libusb_context* ctx, libusb_device
usb_manager* obj = (usb_manager*)monitor; usb_manager* obj = (usb_manager*)monitor;
// if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) // if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)
libusb_ref_device(device); libusb_ref_device(device); // keep the object until handle it
//else if(event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) //else if(event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
// libusb_unref_device(device); // libusb_unref_device(device);
@ -236,8 +236,7 @@ void usb_manager::notify_usb_event(PNPDEV& pd, bool* retry)
retry = &re_try; retry = &re_try;
usb_cb_(ev, pd.dev, ud.vid, ud.pid, HIBYTE(ud.ver), LOBYTE(ud.ver) / 0x10, retry, usb_cb_param_); usb_cb_(ev, pd.dev, ud.vid, ud.pid, HIBYTE(ud.ver), LOBYTE(ud.ver) / 0x10, retry, usb_cb_param_);
} }
if(LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == pd.event) libusb_unref_device(pd.dev); // response for libusb_ref_device in usb_manager::usb_pnp_callback
libusb_unref_device(pd.dev);
} }
void usb_manager::thread_trigger_usb_event() void usb_manager::thread_trigger_usb_event()
{ {

View File

@ -59,7 +59,7 @@ namespace local_utility
RETURN_MATCH_ERROR(SCANNER_ERR_IO, SANE_STATUS_IO_ERROR); RETURN_MATCH_ERROR(SCANNER_ERR_IO, SANE_STATUS_IO_ERROR);
RETURN_MATCH_ERROR(SCANNER_ERR_TIMEOUT, SANE_STATUS_IO_ERROR); RETURN_MATCH_ERROR(SCANNER_ERR_TIMEOUT, SANE_STATUS_IO_ERROR);
RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_NOT_FOUND, SANE_STATUS_NO_DOCS); // RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_NOT_FOUND, SANE_STATUS_NO_DOCS);
RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_NOT_SUPPORT, SANE_STATUS_UNSUPPORTED); RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_NOT_SUPPORT, SANE_STATUS_UNSUPPORTED);
RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_BUSY, SANE_STATUS_DEVICE_BUSY); RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_BUSY, SANE_STATUS_DEVICE_BUSY);
RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_COVER_OPENNED, SANE_STATUS_COVER_OPEN); RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_COVER_OPENNED, SANE_STATUS_COVER_OPEN);