fix bug-242: 超时的异步操作取走后续消息

This commit is contained in:
gb 2022-08-06 14:21:39 +08:00
parent efbc07917c
commit 9babe4b2d3
2 changed files with 26 additions and 14 deletions

View File

@ -81,6 +81,11 @@ void ovl_cls::reset(void)
memset(&ovl_, 0, sizeof(ovl_)); memset(&ovl_, 0, sizeof(ovl_));
ovl_.hEvent = h; ovl_.hEvent = h;
io_bytes_ = 0; io_bytes_ = 0;
ResetEvent(h);
}
bool ovl_cls::is_waited(void)
{
return WaitForSingleObject(ovl_.hEvent, 0) == WAIT_OBJECT_0;
} }
ovl_mgr::ovl_mgr() ovl_mgr::ovl_mgr()
@ -98,9 +103,8 @@ ovl_cls* ovl_mgr::get_ovl(void)
for (auto& v : ovls_) for (auto& v : ovls_)
{ {
if (WaitForSingleObject(v->over_lapped()->hEvent, 0) == WAIT_OBJECT_0) if (v->is_waited())
{ {
ResetEvent(v->over_lapped()->hEvent);
o = v; o = v;
o->add_ref(); o->add_ref();
o->reset(); o->reset();
@ -740,7 +744,7 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
int usb_device::transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16_t ind, unsigned char* data, uint16_t len, unsigned timeout) int usb_device::transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16_t ind, unsigned char* data, uint16_t len, unsigned timeout)
{ {
// return transfer bytes ... // return transfer bytes ...
int ret = LIBUSB_ERROR_NOT_FOUND; int ret = 0; // LIBUSB_ERROR_NOT_FOUND;
_IO_BLOCK_EX irp; _IO_BLOCK_EX irp;
if ((HANDLE)handle_ != INVALID_HANDLE_VALUE) if ((HANDLE)handle_ != INVALID_HANDLE_VALUE)
@ -769,17 +773,18 @@ int usb_device::transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16
} }
else if (GetLastError() == ERROR_IO_PENDING) else if (GetLastError() == ERROR_IO_PENDING)
{ {
ret = WaitForSingleObject(oc->over_lapped()->hEvent, timeout) == WAIT_TIMEOUT ? LIBUSB_ERROR_TIMEOUT : *oc->io_bytes(); ret = WaitForSingleObject(oc->over_lapped()->hEvent, timeout) == WAIT_TIMEOUT ? 0 : *oc->io_bytes();
} }
else else
{ {
io = GetLastError(); //io = GetLastError();
if (io == ERROR_ACCESS_DENIED) //if (io == ERROR_ACCESS_DENIED)
ret = LIBUSB_ERROR_ACCESS; // ret = LIBUSB_ERROR_ACCESS;
else if (io == ERROR_SEM_TIMEOUT) //else if (io == ERROR_SEM_TIMEOUT)
ret = LIBUSB_ERROR_TIMEOUT; // ret = LIBUSB_ERROR_TIMEOUT;
else //else
ret = LIBUSB_ERROR_PIPE; // ret = LIBUSB_ERROR_PIPE;
ret = 0;
} }
oc->release(); oc->release();
} }
@ -788,14 +793,15 @@ int usb_device::transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16
} }
int usb_device::transfer_interrupt(unsigned endpoint, unsigned char* data, int* length, unsigned int timeout) int usb_device::transfer_interrupt(unsigned endpoint, unsigned char* data, int* length, unsigned int timeout)
{ {
int ret = LIBUSB_ERROR_NOT_SUPPORTED; int ret = LIBUSB_ERROR_NOT_SUPPORTED, len = *length;
HANDLE h = find_pipe(endpoint, USBSCAN_PIPE_INTERRUPT); HANDLE h = find_pipe(endpoint, USBSCAN_PIPE_INTERRUPT);
DWORD io = 0; DWORD io = 0;
*length = 0;
if (h) if (h)
{ {
ovl_cls* oc = ovl_mgr_.get_ovl(); ovl_cls* oc = ovl_mgr_.get_ovl();
if (DeviceIoControl(h, IOCTL_WAIT_ON_DEVICE_EVENT, NULL, 0, data, *length, oc->io_bytes(), oc->over_lapped())) if (DeviceIoControl(h, IOCTL_WAIT_ON_DEVICE_EVENT, NULL, 0, data, len, oc->io_bytes(), oc->over_lapped()))
{ {
ret = LIBUSB_SUCCESS; ret = LIBUSB_SUCCESS;
*length = *oc->io_bytes(); *length = *oc->io_bytes();
@ -812,7 +818,12 @@ int usb_device::transfer_interrupt(unsigned endpoint, unsigned char* data, int*
ret = LIBUSB_SUCCESS; ret = LIBUSB_SUCCESS;
} }
else else
{
ret = LIBUSB_ERROR_TIMEOUT; ret = LIBUSB_ERROR_TIMEOUT;
// 此错误可能导致后续新产生的数据被填充进data故取消该操作 BUG-242
CancelIo(h);
}
} }
else else
ret = LIBUSB_ERROR_PIPE; ret = LIBUSB_ERROR_PIPE;

View File

@ -46,6 +46,7 @@ public:
LPOVERLAPPED over_lapped(void); LPOVERLAPPED over_lapped(void);
LPDWORD io_bytes(void); LPDWORD io_bytes(void);
void reset(void); void reset(void);
bool is_waited(void);
}; };
class ovl_mgr class ovl_mgr
{ {